不理解：5.5.1处理override属性
5.7.2 循环依赖解决
6.5.1 增加Spel语言的支持
6.5.2 增加属性注册编辑器
6.6.1 激活注册的BeanFactoryPostProcessor
第二章：容器的基本实现

2.5 容器的基础XmlBeanFactory

2.5.1配置文件封装
//具体看pdf的介绍
public interface InputStreamSource {

	InputStream getInputStream() throws IOException;

}
//具体看pdf的介绍
public interface Resource extends InputStreamSource {


	boolean exists();
	boolean isReadable();
	boolean isOpen();
	URL getURL() throws IOException;
	URI getURI() throws IOException;
	File getFile() throws IOException;
	long contentLength() throws IOException;
	long lastModified() throws IOException;
	Resource createRelative(String relativePath) throws IOException;
	String getFilename();
	String getDescription();

}
重要提示：
    对不同来源的资源文件都有相应的Resource实现：文件(FileSystemResource)、Classpath资源(ClassPathResource)、
(ClassPathResource)、URL资源(UrlResource)、InputStream资源(InputStreamResource)、Byte数组(ByteArrayResource)等。	

类ClassPathResource：
	public InputStream getInputStream() throws IOException {
		InputStream is;
		if (this.clazz != null) {
			is = this.clazz.getResourceAsStream(this.path);
		}
		else if (this.classLoader != null) {
			is = this.classLoader.getResourceAsStream(this.path);
		}
		else {
			is = ClassLoader.getSystemResourceAsStream(this.path);
		}
		if (is == null) {
			throw new FileNotFoundException(getDescription() + " cannot be opened because it does not exist");
		}
		return is;
	}




类XmlBeanFactory：
	public XmlBeanFactory(Resource resource) throws BeansException {
		//（调用XmlBeanFactory(Resource,BeanFactory)构造方法）
		this(resource, null);
	}

	//（parentBeanFactory为父类BeanFactory用于factory合并，可以为空）
类XmlBeanFactory：	
	public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException {
		//super(parentBeanFactory)调用父类构造方法，后面有详细介绍
		super(parentBeanFactory);
		//loadBeanDefinitions方法后面有详细介绍
		this.reader.loadBeanDefinitions(resource);
	}
类AbstractAutowireCapableBeanFactory：
	public AbstractAutowireCapableBeanFactory() {
		super();
		//ignoreDependencyInterface方法为忽略给定接口，详细看pdf
		ignoreDependencyInterface(BeanNameAware.class);
		ignoreDependencyInterface(BeanFactoryAware.class);
		ignoreDependencyInterface(BeanClassLoaderAware.class);
	}
类XmlBeanFactory：	
	public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
		//EncodedResource后面有详细介绍
		return loadBeanDefinitions(new EncodedResource(resource));
	}
类XmlBeanDefinitionReader：
	public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
		//猜：判断encodedResource是否不为空
		Assert.notNull(encodedResource, "EncodedResource must not be null");
		if (logger.isInfoEnabled()) {
			logger.info("Loading XML bean definitions from " + encodedResource.getResource());
		}
		//（通过属性来记录已经加载的资源）
		resourcesCurrentlyBeingLoaded为ThreadLocal类
		Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();
		if (currentResources == null) {
			//猜：第一次为空，创建并加入到resourcesCurrentlyBeingLoaded中
			currentResources = new HashSet<EncodedResource>(4);
			this.resourcesCurrentlyBeingLoaded.set(currentResources);
		}
		//猜：把编码放入到Set集合currentResources，不成功抛异常
		if (!currentResources.add(encodedResource)) {
			throw new BeanDefinitionStoreException(
					"Detected cyclic loading of " + encodedResource + " - check your import definitions!");
		}
		try {
			//（从encodeResource中获取已经封装的Resource对象并再次从Resource中获取其中的inputStream）
			InputStream inputStream = encodedResource.getResource().getInputStream();
			try {
				//（InputSource这个类并不来自于Spring，它的全路径是org.xml.sax.InputSource）
				InputSource inputSource = new InputSource(inputStream);
				//测试：encodedResource.getEncoding()：null 没进入此判断
				if (encodedResource.getEncoding() != null) {
					inputSource.setEncoding(encodedResource.getEncoding());
				}
				//（真正进入了逻辑核心部分）
				//doLoadBeanDefinitions方法后面有详细介绍
				return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
			}
			finally {
				//（关闭输入流）
				inputStream.close();
			}
		}
		catch (IOException ex) {
			throw new BeanDefinitionStoreException(
					"IOException parsing XML document from " + encodedResource.getResource(), ex);
		}
		finally {
			//猜：最后清空信息
			currentResources.remove(encodedResource);
			if (currentResources.isEmpty()) {
				this.resourcesCurrentlyBeingLoaded.remove();
			}
		}
	}	
	
类XmlBeanDefinitionReader：	
	protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
			throws BeanDefinitionStoreException {
		try {
			//（获取对XML文件的验证模式，加载XML文件，并得到对应的Document(pdf)）
			//doLoadDocument方法后面有详细介绍
			Document doc = doLoadDocument(inputSource, resource);
			//（根据返回的Document注册Bean信息(pdf)）
			//registerBeanDefinitions方法后面有详细介绍
			return registerBeanDefinitions(doc, resource);
		}
		catch (BeanDefinitionStoreException ex) {
			throw ex;
		}
		catch (SAXParseException ex) {
			throw new XmlBeanDefinitionStoreException(resource.getDescription(),
					"Line " + ex.getLineNumber() + " in XML document from " + resource + " is invalid", ex);
		}
		catch (SAXException ex) {
			throw new XmlBeanDefinitionStoreException(resource.getDescription(),
					"XML document from " + resource + " is invalid", ex);
		}
		catch (ParserConfigurationException ex) {
			throw new BeanDefinitionStoreException(resource.getDescription(),
					"Parser configuration exception parsing XML from " + resource, ex);
		}
		catch (IOException ex) {
			throw new BeanDefinitionStoreException(resource.getDescription(),
					"IOException parsing XML document from " + resource, ex);
		}
		catch (Throwable ex) {
			throw new BeanDefinitionStoreException(resource.getDescription(),
					"Unexpected exception parsing XML document from " + resource, ex);
		}
	}

类XmlBeanDefinitionReader：	
	protected Document doLoadDocument(InputSource inputSource, Resource resource) throws Exception {
		//loadDocument方法后面有详细介绍
		//getValidationModeForResource方法后面有详细介绍
		return this.documentLoader.loadDocument(inputSource, getEntityResolver(), this.errorHandler,
				getValidationModeForResource(resource), isNamespaceAware());
	}	

2.6.1 DTD与XSD区别	
	
2.6.2 验证模式的读取

类XmlBeanDefinitionReader：	
	protected int getValidationModeForResource(Resource resource) {
		int validationModeToUse = getValidationMode();
		//如果手动指定了验证模式则使用指定的验证模式
		if (validationModeToUse != VALIDATION_AUTO) {
			return validationModeToUse;
		}
		//如果未指定则使用自动检测
		//detectValidationMode方法后面有详细介绍
		int detectedMode = detectValidationMode(resource);
		if (detectedMode != VALIDATION_AUTO) {
			return detectedMode;
		}

		return VALIDATION_XSD;
	}
类XmlBeanDefinitionReader：
	protected int detectValidationMode(Resource resource) {
		//判断是否用不是resource的实现类，不是则抛异常
		//http://blog.sina.com.cn/s/blog_4e193c930100qsw7.html
		if (resource.isOpen()) {
			throw new BeanDefinitionStoreException(
					"Passed-in Resource [" + resource + "] contains an open stream: " +
					"cannot determine validation mode automatically. Either pass in a Resource " +
					"that is able to create fresh streams, or explicitly specify the validationMode " +
					"on your XmlBeanDefinitionReader instance.");
		}

		InputStream inputStream;
		try {
			inputStream = resource.getInputStream();
		}
		catch (IOException ex) {
			throw new BeanDefinitionStoreException(
					"Unable to determine validation mode for [" + resource + "]: cannot open InputStream. " +
					"Did you attempt to load directly from a SAX InputSource without specifying the " +
					"validationMode on your XmlBeanDefinitionReader instance?", ex);
		}

		try {
			//detectValidationMode方法后面有详细介绍
			return this.validationModeDetector.detectValidationMode(inputStream);
		}
		catch (IOException ex) {
			throw new BeanDefinitionStoreException("Unable to determine validation mode for [" +
					resource + "]: an error occurred whilst reading from the InputStream.", ex);
		}
	}

类XmlValidationModeDetector：
	public int detectValidationMode(InputStream inputStream) throws IOException {
		// Peek into the file to look for DOCTYPE.
		//猜：创建输出流进行读取配置文件
		BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
		try {
			boolean isDtdValidated = false;
			String content;
			//猜：读取每一行
			while ((content = reader.readLine()) != null) {
				//consumeCommentTokens方法为去掉注释
				content = consumeCommentTokens(content);
				//（如果读取的行是空或者是注释则略过）
				if (this.inComment || !StringUtils.hasText(content)) {
					continue;
				}
				//hasDoctype后面有详细介绍
				//猜：包含DOCTYPE为DTD模式
				if (hasDoctype(content)) {
					isDtdValidated = true;
					break;
				}
				//（读取到<开始符号，验证模式一定会在开始符号之前）
				//猜：判断为XSD
				if (hasOpeningTag(content)) {
					// End of meaningful data...
					break;
				}
			}
			return (isDtdValidated ? VALIDATION_DTD : VALIDATION_XSD);
		}
		catch (CharConversionException ex) {
			// Choked on some character encoding...
			// Leave the decision up to the caller.
			return VALIDATION_AUTO;
		}
		finally {
			reader.close();
		}
	}
2.7 获取Document
	
类DefaultDocumentLoader：
	//https://blog.csdn.net/hua1017177499/article/details/78985166
	//通过SAX解析XML
	public Document loadDocument(InputSource inputSource, EntityResolver entityResolver,
			ErrorHandler errorHandler, int validationMode, boolean namespaceAware) throws Exception {

		//通过DocumentBuilderFactory来解析XML		
		DocumentBuilderFactory factory = createDocumentBuilderFactory(validationMode, namespaceAware);
		if (logger.isDebugEnabled()) {
			logger.debug("Using JAXP provider [" + factory.getClass().getName() + "]");
		}
		//调用 DOM 解析器对象的 parse() 方法解析 XML 文档，得到代表整个文档的 Document 对象
		DocumentBuilder builder = createDocumentBuilder(factory, entityResolver, errorHandler);
		return builder.parse(inputSource);
	}	

类DefaultDocumentLoader：	
	protected DocumentBuilderFactory createDocumentBuilderFactory(int validationMode, boolean namespaceAware)
			throws ParserConfigurationException {

		//通过DocumentBuilderFactory来解析XML	
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		factory.setNamespaceAware(namespaceAware);

		if (validationMode != XmlValidationModeDetector.VALIDATION_NONE) {
			factory.setValidating(true);
			if (validationMode == XmlValidationModeDetector.VALIDATION_XSD) {
				// Enforce namespace aware for XSD...
				factory.setNamespaceAware(true);
				try {
					factory.setAttribute(SCHEMA_LANGUAGE_ATTRIBUTE, XSD_SCHEMA_LANGUAGE);
				}
				catch (IllegalArgumentException ex) {
					ParserConfigurationException pcex = new ParserConfigurationException(
							"Unable to validate using XSD: Your JAXP provider [" + factory +
							"] does not support XML Schema. Are you running on Java 1.4 with Apache Crimson? " +
							"Upgrade to Apache Xerces (or Java 1.5) for full XSD support.");
					pcex.initCause(ex);
					throw pcex;
				}
			}
		}

		return factory;
	}
类DefaultDocumentLoader：
	protected DocumentBuilder createDocumentBuilder(
			DocumentBuilderFactory factory, EntityResolver entityResolver, ErrorHandler errorHandler)
			throws ParserConfigurationException {

		DocumentBuilder docBuilder = factory.newDocumentBuilder();
		if (entityResolver != null) {
			docBuilder.setEntityResolver(entityResolver);
		}
		if (errorHandler != null) {
			docBuilder.setErrorHandler(errorHandler);
		}
		return docBuilder;
	}
类XmlBeanDefinitionReader：
	protected EntityResolver getEntityResolver() {
		if (this.entityResolver == null) {
			// Determine default EntityResolver to use.
			ResourceLoader resourceLoader = getResourceLoader();
			if (resourceLoader != null) {
				this.entityResolver = new ResourceEntityResolver(resourceLoader);
			}
			else {
				this.entityResolver = new DelegatingEntityResolver(getBeanClassLoader());
			}
		}
		return this.entityResolver;
	}	


2.7.1 EntityResolver 用法（pdf中有详细介绍）

类DelegatingEntityResolver：
	public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
		if (systemId != null) {
			if (systemId.endsWith(DTD_SUFFIX)) {
				//（如果dtd从这里解析）
				return this.dtdResolver.resolveEntity(publicId, systemId);
			}
			else if (systemId.endsWith(XSD_SUFFIX)) {
				//（通过调用META-INF/Spring.schemas解析）
				return this.schemaResolver.resolveEntity(publicId, systemId);
			}
		}
		return null;
	}
类BeansDtdResolver：
	public InputSource resolveEntity(String publicId, String systemId) throws IOException {
		if (logger.isTraceEnabled()) {
			logger.trace("Trying to resolve XML entity with public ID [" + publicId +
					"] and system ID [" + systemId + "]");
		}
		//（DTD_EXTENSION = ".dtd"）
		if (systemId != null && systemId.endsWith(DTD_EXTENSION)) {
			int lastPathSeparator = systemId.lastIndexOf("/");
			//
			int dtdNameStart = systemId.indexOf(DTD_NAME, lastPathSeparator);
			if (dtdNameStart != -1) {
				//测试：dtdFile：BeansDtdResolver
				String dtdFile = DTD_FILENAME + DTD_EXTENSION;
				if (logger.isTraceEnabled()) {
					logger.trace("Trying to locate [" + dtdFile + "] in Spring jar on classpath");
				}
				try {
					//ClassPathResource类，如果没有指定相对的类名，该类将从类的根路径开始寻找某个resource，
					//如果指定了相对的类名，则根据指定类的相对路径来查找某个resource。
					Resource resource = new ClassPathResource(dtdFile, getClass());
					//从resource获得输入流
					InputSource source = new InputSource(resource.getInputStream());
					source.setPublicId(publicId);
					source.setSystemId(systemId);
					if (logger.isDebugEnabled()) {
						logger.debug("Found beans DTD [" + systemId + "] in classpath: " + dtdFile);
					}
					return source;
				}
				catch (IOException ex) {
					if (logger.isDebugEnabled()) {
						logger.debug("Could not resolve beans DTD [" + systemId + "]: not found in classpath", ex);
					}
				}

			}
		}

		// Use the default behavior -> download from website or wherever.
		return null;
	}


2.8 解析及注册BeanDefinitions
类XmlBeanDefinitionReader：
	public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
		
		//（使用DefaultBeanDefinitionDocumentReader实例化BeanDefinitionDocumentReader）
		//看：使用反射的cast命令强转为BeanDefinitionDocumentReader
		BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
		//（在实例化BeanDefinitionReader时候将BeanDefinitionRegistry传入，默认使用继承自
		//DefaultListableBeanFactory的子类）
		int countBefore = getRegistry().getBeanDefinitionCount();
		//（加载及注册bean）
		//registerBeanDefinitions方法后面有详细介绍
		documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
		//（记录本次加载的BeanDefinition个数）
		return getRegistry().getBeanDefinitionCount() - countBefore;
	}	
类DefaultBeanDefinitionDocumentReader：	
	public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
		this.readerContext = readerContext;
		logger.debug("Loading bean definitions");
		//猜：获得根节点
		Element root = doc.getDocumentElement();
		//doRegisterBeanDefinitions方法后面有详细介绍
		doRegisterBeanDefinitions(root);
	}	

	
类DefaultBeanDefinitionDocumentReader：		
	protected void doRegisterBeanDefinitions(Element root) {

		//（专门处理解析）
		BeanDefinitionParserDelegate parent = this.delegate;
		//createDelegate方法不清楚
		this.delegate = createDelegate(getReaderContext(), root, parent);
		
		//（处理profile属性）
		if (this.delegate.isDefaultNamespace(root)) {
			String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
			if (StringUtils.hasText(profileSpec)) {
				String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
						profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
				if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
					return;
				}
			}
		}
		//（解析前处理，留给子类实现）
		//看:方法内部为空
		preProcessXml(root);
		//parseBeanDefinitions方法后面有详细介绍
		parseBeanDefinitions(root, this.delegate);
		//（解析后处理，留给子类实现）
		//看:方法内部为空
		postProcessXml(root);

		this.delegate = parent;
	}

类DefaultBeanDefinitionDocumentReader：	
	protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
		//（对beans的处理）
		if (delegate.isDefaultNamespace(root)) {
			NodeList nl = root.getChildNodes();
			for (int i = 0; i < nl.getLength(); i++) {
				Node node = nl.item(i);
				if (node instanceof Element) {
					Element ele = (Element) node;
					//（对bean的处理）
					//猜：从字面的意思是默认Bean的解析
					if (delegate.isDefaultNamespace(ele)) {
						parseDefaultElement(ele, delegate);
					}
					else {
						//（对bean的处理）
						//猜：从字面的意思是用户自定义Bean的解析
						delegate.parseCustomElement(ele);
					}
				}
			}
		}
		else {
			delegate.parseCustomElement(root);
		}
	}	


第三章 默认标签的解析

类DefaultBeanDefinitionDocumentReader：

	private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
		//（对import标签的处理）
		if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
			importBeanDefinitionResource(ele);
		}
		//（对alias标签的处理）
		else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
			processAliasRegistration(ele);
		}
		//（对bean标签的处理）
		else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
			processBeanDefinition(ele, delegate);
		}
		//（对beans标签的处理）
		else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
			// recurse
			doRegisterBeanDefinitions(ele);
		}
	}

	
3.1 bean标签的解析及注册

类DefaultBeanDefinitionDocumentReader：
	protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
		//parseBeanDefinitionElement方法后面有详细介绍
		//（首先委托BeanDefinitionDelegate类的parseBeanDefinitionElement方法进行元素解析，
		//返回BeanDefinitionHolder类型的实例bdHolder，经过这个方法后，bdHolder实例已经包含
		//我们配置文件中配置的各种属性了，例如：class、name、id、等属性）
		BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
		if (bdHolder != null) {
			//decorateBeanDefinitionIfRequired方法后面有详细介绍
			//（当返回的bdHolder不为空的情况下若存在默认标签的子节点再有自定义属性，还需
			//再次对自定义标签进行解析）
			bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
			try {
				// Register the final decorated instance.
				//registerBeanDefinition方法后面有详细介绍
				//（解析完成后，需要对解析后的bdHolder进行注册，同样，注册操作委托给了Bean
				//DefinitionReaderUtils的registerBeanDefinition方法）
				BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
			}
			catch (BeanDefinitionStoreException ex) {
				getReaderContext().error("Failed to register bean definition with name '" +
						bdHolder.getBeanName() + "'", ele, ex);
			}
			// Send registration event.
			//fireComponentRegistered方法后面有详细介绍
			//（最后发出响应事件，通知相关的监听器，这个bean已经加载完成了）
			getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
		}
	}
	
3.1.1 解析BeanDefinition

类BeanDefinitionParserDelegate：
	public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) {
		//parseBeanDefinitionElement方法后面有详细介绍
		return parseBeanDefinitionElement(ele, null);
	}

类BeanDefinitionParserDelegate：
	public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
		//（解析id属性）
		//猜：获得配置文件中的id属性值
		//getAttribute为Element的方法
		//测试：id：user
		String id = ele.getAttribute(ID_ATTRIBUTE);
		//（解析name属性）
		//测试：nameAttr：""
		//（1）
		String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);

		//（分割name属性）
		//猜：可以配置多个name属性
		List<String> aliases = new ArrayList<String>();
		if (StringUtils.hasLength(nameAttr)) {
			//测试：MULTI_VALUE_ATTRIBUTE_DELIMITERS：,; 
			//猜：以,; 为分割开nameAttr属性
			String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
			aliases.addAll(Arrays.asList(nameArr));
		}

		String beanName = id;
		//猜：beanName没值，而aliases有值，就把aliases作为beanName
		if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
			beanName = aliases.remove(0);
			if (logger.isDebugEnabled()) {
				logger.debug("No XML 'id' specified - using '" + beanName +
						"' as bean name and " + aliases + " as aliases");
			}
		}

		if (containingBean == null) {
			//猜：检查这个bean是否有注册过
			//checkNameUniqueness方法具体不清楚
			checkNameUniqueness(beanName, aliases, ele);
		}

		//parseBeanDefinitionElement方法后面有详细介绍
		//测试：beanDefinition：封装着各属性的GenericBeanDifinition类，Generic bean: class [com.dodi.spring.profile.User]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in class path resource [profile/applicationContext.xml]
		//（2）
		AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
		if (beanDefinition != null) {
			//（3）
			if (!StringUtils.hasText(beanName)) {
				try {
					//（如果不存在beanName，那么根据Spring中提供的命名规则为当前bean生成对应的beanName）
					if (containingBean != null) {
						//猜：containingBean不为空则从里面获取
						//测试时没进入
						beanName = BeanDefinitionReaderUtils.generateBeanName(
								beanDefinition, this.readerContext.getRegistry(), true);
					}
					else {
						//测试：beanName：com.dodi.spring.pojo.User#0
						//https://blog.csdn.net/evilcry2013/article/details/78962975
						//看：判断是否有父类，工厂类，innerBean
						beanName = this.readerContext.generateBeanName(beanDefinition);
						// Register an alias for the plain bean class name, if still possible,
						// if the generator returned the class name plus a suffix.
						// This is expected for Spring 1.2/2.0 backwards compatibility.
						//猜：从beanDefinition中获得class属性
						//测试：com.dodi.spring.pojo.User
						String beanClassName = beanDefinition.getBeanClassName();
						if (beanClassName != null &&
								beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() &&
								!this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
							aliases.add(beanClassName);
						}
					}
					if (logger.isDebugEnabled()) {
						logger.debug("Neither XML 'id' nor 'name' specified - " +
								"using generated bean name [" + beanName + "]");
					}
				}
				catch (Exception ex) {
					error(ex.getMessage(), ele);
					return null;
				}
			}
			//测试：aliasesArray：[]
			String[] aliasesArray = StringUtils.toStringArray(aliases);
			//（4）
			return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
		}

		return null;
	}	
类BeanDefinitionParserDelegate：	
	public AbstractBeanDefinition parseBeanDefinitionElement(
			Element ele, String beanName, BeanDefinition containingBean) {

		this.parseState.push(new BeanEntry(beanName));

		String className = null;
		//（解析class属性）
		if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
			className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
		}

		try {
			String parent = null;
			//（解析parent属性）
			if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
				parent = ele.getAttribute(PARENT_ATTRIBUTE);
			}
			//（创建用于承载属性的AbstractBeanDefinition类型的GenericBeanDefinition）
			//createBeanDefinition方法后面有详细介绍
			AbstractBeanDefinition bd = createBeanDefinition(className, parent);

			//（硬编码解析默认bean的各种属性）
			//以下方法后面有详细介绍
			parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
			//（提取description）
			bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));

			//（解析元数据）
			//以下方法后面有详细介绍
			parseMetaElements(ele, bd);
			//（解析lookup-method属性）
			//以下方法后面有详细介绍
			parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
			//（解析replaced-method属性）
			//以下方法后面有详细介绍
			parseReplacedMethodSubElements(ele, bd.getMethodOverrides());

			//（解析构造函数参数）
			//以下方法后面有详细介绍
			parseConstructorArgElements(ele, bd);
			//（解析property子元素）
			//以下方法后面有详细介绍
			parsePropertyElements(ele, bd);
			//（解析qualifier子元素）
			//以下方法后面有详细介绍
			parseQualifierElements(ele, bd);

			bd.setResource(this.readerContext.getResource());
			bd.setSource(extractSource(ele));

			return bd;
		}
		catch (ClassNotFoundException ex) {
			error("Bean class [" + className + "] not found", ele, ex);
		}
		catch (NoClassDefFoundError err) {
			error("Class that bean class [" + className + "] depends on not found", ele, err);
		}
		catch (Throwable ex) {
			error("Unexpected failure during bean definition parsing", ele, ex);
		}
		finally {
			this.parseState.pop();
		}

		return null;
	}	
	
1.创建用于属性承载的BeanDefinition
重点提示：
   BeanDefinition是一个接口，在Spring中存在三种实现：RootBeanDefinition、ChildBeanDefinition
以及GenericBeanDefinition。三种实现均继承了AbstractBeanDefinition，其中BeanDefinition是配置文件
<bean>元素标签在容器中的内部表示形式。<bean>元素标签拥有class、scope、lazy-init等配置属性，BeanDefinition
则提供了相应的beanClass、scope、lazyInit属性，BeanDefinition和<bean>中的属性是一一对应的。其中RootBeanDefinition是
最常用的实现类，它对应一般性的<bean>元素标签。
   在配置文件中刻印定义父<bean>和子<bean>，父<bean>用RootBeanDefinition表示，而子<bean>用ChildBeanDefinition
表示，而没有父<bean>的<bean>就使用RootBeanDefinition表示。AbstractBeanDefinition对两者共同的类信息进行抽象。
	Spring通过BeanDefini将配置文件中的<bean>配置信息转换为容器的内部表示，并将这些BeanDefinition
注册到BeanDefinitionRegistry中，Spring容器的BeanDefinitionRegistry就像是Spring配置信息的内存数据库，主要以map大的形式
保存，后续操作直接从BeanDefinitionRegistry中读取配置信息。	
	GenericBeanDefinition它支持动态定义父依赖，方法是GenericBeanDefinition.setParentName(java.lang.String),GenericBeanDefinition
可以有效的替代ChildBeanDefinition的绝大部分使用场合。	
	

类BeanDefinitionParserDelegate：	
	protected AbstractBeanDefinition createBeanDefinition(String className, String parentName)
			throws ClassNotFoundException {

		return BeanDefinitionReaderUtils.createBeanDefinition(
				parentName, className, this.readerContext.getBeanClassLoader());
	}	
	
类BeanDefinitionReaderUtils：
	public static AbstractBeanDefinition createBeanDefinition(
			String parentName, String className, ClassLoader classLoader) throws ClassNotFoundException {

		GenericBeanDefinition bd = new GenericBeanDefinition();
		//（parentName可能为空）
		bd.setParentName(parentName);
		if (className != null) {
			if (classLoader != null) {
				//（如果classLoder不为空，则使用以传入的classLoader同一虚拟机加载类对象，否则只是记录className）
				bd.setBeanClass(ClassUtils.forName(className, classLoader));
			}
			else {
				bd.setBeanClassName(className);
			}
		}
		return bd;
	}	
	
2. 解析各种属性

类BeanDefinitionParserDelegate：
	public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String beanName,
			BeanDefinition containingBean, AbstractBeanDefinition bd) {

		//singelton属性已经被scope取代
		//（解析scope属性）
		if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) {
			error("Old 1.x 'singleton' attribute in use - upgrade to 'scope' declaration", ele);
		}
		else if (ele.hasAttribute(SCOPE_ATTRIBUTE)) {
			bd.setScope(ele.getAttribute(SCOPE_ATTRIBUTE));
		}
		else if (containingBean != null) {
			// Take default from containing bean in case of an inner bean definition.
			bd.setScope(containingBean.getScope());
		}
		//（解析absract属性）
		if (ele.hasAttribute(ABSTRACT_ATTRIBUTE)) {
			bd.setAbstract(TRUE_VALUE.equals(ele.getAttribute(ABSTRACT_ATTRIBUTE)));
		}
		//（解析lazy-init属性）
		String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE);
		if (DEFAULT_VALUE.equals(lazyInit)) {
			lazyInit = this.defaults.getLazyInit();
		}
		//（若没有设置或设置成其他字符都会设置为false）
		bd.setLazyInit(TRUE_VALUE.equals(lazyInit));

		//（解析autowire属性）
		String autowire = ele.getAttribute(AUTOWIRE_ATTRIBUTE);
		bd.setAutowireMode(getAutowireMode(autowire));
		//（解析dependency-check属性）
		String dependencyCheck = ele.getAttribute(DEPENDENCY_CHECK_ATTRIBUTE);
		bd.setDependencyCheck(getDependencyCheck(dependencyCheck));
		//（解析depends-on属性）
		if (ele.hasAttribute(DEPENDS_ON_ATTRIBUTE)) {
			String dependsOn = ele.getAttribute(DEPENDS_ON_ATTRIBUTE);
			bd.setDependsOn(StringUtils.tokenizeToStringArray(dependsOn, MULTI_VALUE_ATTRIBUTE_DELIMITERS));
		}
		//（解析autowire-candidate属性）
		String autowireCandidate = ele.getAttribute(AUTOWIRE_CANDIDATE_ATTRIBUTE);
		if ("".equals(autowireCandidate) || DEFAULT_VALUE.equals(autowireCandidate)) {
			String candidatePattern = this.defaults.getAutowireCandidates();
			if (candidatePattern != null) {
				String[] patterns = StringUtils.commaDelimitedListToStringArray(candidatePattern);
				bd.setAutowireCandidate(PatternMatchUtils.simpleMatch(patterns, beanName));
			}
		}
		else {
			bd.setAutowireCandidate(TRUE_VALUE.equals(autowireCandidate));
		}
		//（解析primary属性）
		if (ele.hasAttribute(PRIMARY_ATTRIBUTE)) {
			bd.setPrimary(TRUE_VALUE.equals(ele.getAttribute(PRIMARY_ATTRIBUTE)));
		}
		//（解析init-method属性）
		if (ele.hasAttribute(INIT_METHOD_ATTRIBUTE)) {
			String initMethodName = ele.getAttribute(INIT_METHOD_ATTRIBUTE);
			if (!"".equals(initMethodName)) {
				bd.setInitMethodName(initMethodName);
			}
		}
		else {
			if (this.defaults.getInitMethod() != null) {
				bd.setInitMethodName(this.defaults.getInitMethod());
				bd.setEnforceInitMethod(false);
			}
		}
		//（解析destroy-method属性）
		if (ele.hasAttribute(DESTROY_METHOD_ATTRIBUTE)) {
			String destroyMethodName = ele.getAttribute(DESTROY_METHOD_ATTRIBUTE);
			bd.setDestroyMethodName(destroyMethodName);
		}
		else {
			if (this.defaults.getDestroyMethod() != null) {
				bd.setDestroyMethodName(this.defaults.getDestroyMethod());
				bd.setEnforceDestroyMethod(false);
			}
		}
		//（解析factory-method属性）
		if (ele.hasAttribute(FACTORY_METHOD_ATTRIBUTE)) {
			bd.setFactoryMethodName(ele.getAttribute(FACTORY_METHOD_ATTRIBUTE));
		}
		//（解析factory-bean属性）
		if (ele.hasAttribute(FACTORY_BEAN_ATTRIBUTE)) {
			bd.setFactoryBeanName(ele.getAttribute(FACTORY_BEAN_ATTRIBUTE));
		}

		return bd;
	}	

3.解析子元素meta	
类BeanDefinitionParserDelegate：	
	public void parseMetaElements(Element ele, BeanMetadataAttributeAccessor attributeAccessor) {
		//（获取当前节点的所有子元素）
		NodeList nl = ele.getChildNodes();
		for (int i = 0; i < nl.getLength(); i++) {
			Node node = nl.item(i);
			//（提取meta）
			if (isCandidateElement(node) && nodeNameEquals(node, META_ELEMENT)) {
				Element metaElement = (Element) node;
				String key = metaElement.getAttribute(KEY_ATTRIBUTE);
				String value = metaElement.getAttribute(VALUE_ATTRIBUTE);
				//（使用key、value构造BeanMetadataAttribute）
				BeanMetadataAttribute attribute = new BeanMetadataAttribute(key, value);
				attribute.setSource(extractSource(metaElement));
				//（记录信息）
				attributeAccessor.addMetadataAttribute(attribute);
			}
		}
	}	
	
4. 解析子元素lookup-method

类BeanDefinitionParserDelegate：
	public void parseLookupOverrideSubElements(Element beanEle, MethodOverrides overrides) {
		NodeList nl = beanEle.getChildNodes();
		for (int i = 0; i < nl.getLength(); i++) {
			Node node = nl.item(i);
			//（仅当在Spring默认bean的子元素下且为<lookup-method时有效）
			if (isCandidateElement(node) && nodeNameEquals(node, LOOKUP_METHOD_ELEMENT)) {
				Element ele = (Element) node;
				//（获取要修改的方法）
				String methodName = ele.getAttribute(NAME_ATTRIBUTE);
				//（获取配置返回的bean）
				String beanRef = ele.getAttribute(BEAN_ELEMENT);
				//创建一个LookupOverride类保存methodName和beanRef
				LookupOverride override = new LookupOverride(methodName, beanRef);
				//测试：extractSource(ele)：null
				override.setSource(extractSource(ele));
				overrides.addOverride(override);
			}
		}
	}

类BeanDefinitionParserDelegate：	
	public void parseReplacedMethodSubElements(Element beanEle, MethodOverrides overrides) {
		NodeList nl = beanEle.getChildNodes();
		for (int i = 0; i < nl.getLength(); i++) {
			Node node = nl.item(i);
			//（仅当在Spring默认bean的子元素下且为<replaced-method时有效）
			if (isCandidateElement(node) && nodeNameEquals(node, REPLACED_METHOD_ELEMENT)) {
				Element replacedMethodEle = (Element) node;
				//（提取要替换的旧的方法）
				String name = replacedMethodEle.getAttribute(NAME_ATTRIBUTE);
				//（提取对应的新的替换方法）
				String callback = replacedMethodEle.getAttribute(REPLACER_ATTRIBUTE);
				ReplaceOverride replaceOverride = new ReplaceOverride(name, callback);
				// Look for arg-type match elements.
				//猜：查出替换方法的所有参数
				//测试：argTypeEles为空，以后再看
				List<Element> argTypeEles = DomUtils.getChildElementsByTagName(replacedMethodEle, ARG_TYPE_ELEMENT);
				for (Element argTypeEle : argTypeEles) {
					//（记录参数）
					String match = argTypeEle.getAttribute(ARG_TYPE_MATCH_ATTRIBUTE);
					match = (StringUtils.hasText(match) ? match : DomUtils.getTextValue(argTypeEle));
					if (StringUtils.hasText(match)) {
						replaceOverride.addTypeIdentifier(match);
					}
				}
				//测试：extractSource(replacedMethodEle)：null
				replaceOverride.setSource(extractSource(replacedMethodEle));
				overrides.addOverride(replaceOverride);
			}
		}
	}

6. 解析子元素constructor-arg

类BeanDefinitionParserDelegate：	
	public void parseConstructorArgElements(Element beanEle, BeanDefinition bd) {
		NodeList nl = beanEle.getChildNodes();
		for (int i = 0; i < nl.getLength(); i++) {
			Node node = nl.item(i);
			if (isCandidateElement(node) && nodeNameEquals(node, CONSTRUCTOR_ARG_ELEMENT)) {
				//（解析constructor-arg）
				//parseConstructorArgElement后面有详细介绍
				parseConstructorArgElement((Element) node, bd);
			}
		}
	}	

类BeanDefinitionParserDelegate：	
	public void parseConstructorArgElement(Element ele, BeanDefinition bd) {
		//（提取iddex属性）
		String indexAttr = ele.getAttribute(INDEX_ATTRIBUTE);
		//（提取type属性）
		String typeAttr = ele.getAttribute(TYPE_ATTRIBUTE);
		//（提取name属性）
		String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
		if (StringUtils.hasLength(indexAttr)) {
			try {
				int index = Integer.parseInt(indexAttr);
				if (index < 0) {
					error("'index' cannot be lower than 0", ele);
				}
				else {
					try {
						//以下推栈不清楚
						this.parseState.push(new ConstructorArgumentEntry(index));
						//（解析ele对应的属性元素）
						//（1）
						//parsePropertyValue方法后面有详细介绍
						Object value = parsePropertyValue(ele, bd, null);
						//（2）
						ConstructorArgumentValues.ValueHolder valueHolder = new ConstructorArgumentValues.ValueHolder(value);
						
						//（3）
						if (StringUtils.hasLength(typeAttr)) {
							valueHolder.setType(typeAttr);
						}
						if (StringUtils.hasLength(nameAttr)) {
							valueHolder.setName(nameAttr);
						}
						valueHolder.setSource(extractSource(ele));
						//（不允许重复指定相同参数）
						//猜：判断是否已经有了此参数的定义
						if (bd.getConstructorArgumentValues().hasIndexedArgumentValue(index)) {
							error("Ambiguous constructor-arg entries for index " + index, ele);
						}
						else {
							//addIndexedArgumentValue方法后面有详细介绍
							bd.getConstructorArgumentValues().addIndexedArgumentValue(index, valueHolder);
						}
					}
					finally {
						this.parseState.pop();
					}
				}
			}
			catch (NumberFormatException ex) {
				error("Attribute 'index' of tag 'constructor-arg' must be an integer", ele);
			}
		}
		else {
			//（没有index属性则忽略去属性，自动寻找）
			try {
				this.parseState.push(new ConstructorArgumentEntry());
				//（1）
				Object value = parsePropertyValue(ele, bd, null);
				//（2）
				ConstructorArgumentValues.ValueHolder valueHolder = new ConstructorArgumentValues.ValueHolder(value);
				if (StringUtils.hasLength(typeAttr)) {
					valueHolder.setType(typeAttr);
				}
				if (StringUtils.hasLength(nameAttr)) {
					valueHolder.setName(nameAttr);
				}
				valueHolder.setSource(extractSource(ele));
				//addGenericArgumentValue方法后面有详细介绍
				bd.getConstructorArgumentValues().addGenericArgumentValue(valueHolder);
			}
			finally {
				this.parseState.pop();
			}
		}
	}
类BeanDefinitionParserDelegate：
	public Object parsePropertyValue(Element ele, BeanDefinition bd, String propertyName) {
		String elementName = (propertyName != null) ?
						"<property> element for property '" + propertyName + "'" :
						"<constructor-arg> element";

		// Should only have one child element: ref, value, list, etc.
		//（一个属性只能对应一种类型，ref,value,list等）
		NodeList nl = ele.getChildNodes();
		Element subElement = null;
		for (int i = 0; i < nl.getLength(); i++) {
			Node node = nl.item(i);
			//（对应description或者meta不处理）
			//（1）
			if (node instanceof Element && !nodeNameEquals(node, DESCRIPTION_ELEMENT) &&
					!nodeNameEquals(node, META_ELEMENT)) {
				// Child element is what we're looking for.
				if (subElement != null) {
					error(elementName + " must not contain more than one sub-element", ele);
				}
				else {
					subElement = (Element) node;
				}
			}
		}
		//（2）
		//（解析constructor-arg上的ref属性）
		boolean hasRefAttribute = ele.hasAttribute(REF_ATTRIBUTE);
		//（解析constructor-arg上的value属性）
		boolean hasValueAttribute = ele.hasAttribute(VALUE_ATTRIBUTE);
		if ((hasRefAttribute && hasValueAttribute) ||
				((hasRefAttribute || hasValueAttribute) && subElement != null)) {
			//（在constructor-arg上不存在：
			//   1、同时既有ref属性又又value属性
			//   2、存在ref属性或者value属性又有子元素）
			error(elementName +
					" is only allowed to contain either 'ref' attribute OR 'value' attribute OR sub-element", ele);
		}
		
		if (hasRefAttribute) {
			//（ref属性的处理，使用RuntimeBeanReference封装对应的ref名称）
			//（3）
			String refName = ele.getAttribute(REF_ATTRIBUTE);
			if (!StringUtils.hasText(refName)) {
				error(elementName + " contains empty 'ref' attribute", ele);
			}
			RuntimeBeanReference ref = new RuntimeBeanReference(refName);
			ref.setSource(extractSource(ele));
			return ref;
		}
		else if (hasValueAttribute) {
			//（value属性的处理，使用TypedStringValue封装）
			//（4）
			TypedStringValue valueHolder = new TypedStringValue(ele.getAttribute(VALUE_ATTRIBUTE));
			valueHolder.setSource(extractSource(ele));
			return valueHolder;
		}
		else if (subElement != null) {
			//（解析子元素）
			//（5）
			//parsePropertySubElement方法后面有详细介绍
			return parsePropertySubElement(subElement, bd);
		}
		else {
			// Neither child element nor "ref" or "value" attribute found.
			//（既没有ref也没有value也没有子元素，Spring蒙圈了）
			error(elementName + " must specify a ref or value", ele);
			return null;
		}
	}

类BeanDefinitionParserDelegate：
	public Object parsePropertySubElement(Element ele, BeanDefinition bd) {
		//parsePropertySubElement方法后面有详细介绍
		return parsePropertySubElement(ele, bd, null);
	}
	
类BeanDefinitionParserDelegate：
	public Object parsePropertySubElement(Element ele, BeanDefinition bd, String defaultValueType) {
		if (!isDefaultNamespace(ele)) {
			return parseNestedCustomElement(ele, bd);
		}
		else if (nodeNameEquals(ele, BEAN_ELEMENT)) {
			BeanDefinitionHolder nestedBd = parseBeanDefinitionElement(ele, bd);
			if (nestedBd != null) {
				nestedBd = decorateBeanDefinitionIfRequired(ele, nestedBd, bd);
			}
			return nestedBd;
		}
		else if (nodeNameEquals(ele, REF_ELEMENT)) {
			// A generic reference to any name of any bean.
			String refName = ele.getAttribute(BEAN_REF_ATTRIBUTE);
			boolean toParent = false;
			if (!StringUtils.hasLength(refName)) {
				// A reference to the id of another bean in the same XML file.
				//（解析local）
				refName = ele.getAttribute(LOCAL_REF_ATTRIBUTE);
				if (!StringUtils.hasLength(refName)) {
					// A reference to the id of another bean in a parent context.
					//（解析parent）
					refName = ele.getAttribute(PARENT_REF_ATTRIBUTE);
					toParent = true;
					if (!StringUtils.hasLength(refName)) {
						error("'bean', 'local' or 'parent' is required for <ref> element", ele);
						return null;
					}
				}
			}
			if (!StringUtils.hasText(refName)) {
				error("<ref> element contains empty target attribute", ele);
				return null;
			}
			RuntimeBeanReference ref = new RuntimeBeanReference(refName, toParent);
			ref.setSource(extractSource(ele));
			return ref;
		}
		//（对idref元素解析）
		else if (nodeNameEquals(ele, IDREF_ELEMENT)) {
			return parseIdRefElement(ele);
		}
		//（对value子元素解析）
		else if (nodeNameEquals(ele, VALUE_ELEMENT)) {
			return parseValueElement(ele, defaultValueType);
		}
		//（对null子元素的解析）
		else if (nodeNameEquals(ele, NULL_ELEMENT)) {
			// It's a distinguished null value. Let's wrap it in a TypedStringValue
			// object in order to preserve the source location.
			TypedStringValue nullHolder = new TypedStringValue(null);
			nullHolder.setSource(extractSource(ele));
			return nullHolder;
		}
		else if (nodeNameEquals(ele, ARRAY_ELEMENT)) {
			//（解析array子元素）
			return parseArrayElement(ele, bd);
		}
		else if (nodeNameEquals(ele, LIST_ELEMENT)) {
			//（解析list子元素）
			return parseListElement(ele, bd);
		}
		else if (nodeNameEquals(ele, SET_ELEMENT)) {
			//（解析set子元素）
			return parseSetElement(ele, bd);
		}
		else if (nodeNameEquals(ele, MAP_ELEMENT)) {
			//（解析map子元素）
			return parseMapElement(ele, bd);
		}
		else if (nodeNameEquals(ele, PROPS_ELEMENT)) {
			//（解析props子元素）
			return parsePropsElement(ele);
		}
		else {
			error("Unknown property sub-element: [" + ele.getNodeName() + "]", ele);
			return null;
		}
	}

7. 解析子元素property

类BeanDefinitionParserDelegate：
	public void parsePropertyElements(Element beanEle, BeanDefinition bd) {
		NodeList nl = beanEle.getChildNodes();
		for (int i = 0; i < nl.getLength(); i++) {
			Node node = nl.item(i);
			if (isCandidateElement(node) && nodeNameEquals(node, PROPERTY_ELEMENT)) {
				//parsePropertyElement方法后面有详细描述
				parsePropertyElement((Element) node, bd);
			}
		}
	}

类BeanDefinitionParserDelegate：
	public void parsePropertyElement(Element ele, BeanDefinition bd) {
		//（获取配置元素中name的值）
		String propertyName = ele.getAttribute(NAME_ATTRIBUTE);
		if (!StringUtils.hasLength(propertyName)) {
			error("Tag 'property' must have a 'name' attribute", ele);
			return;
		}
		this.parseState.push(new PropertyEntry(propertyName));
		try {
			//（不允许多次对同一属性配置）
			if (bd.getPropertyValues().contains(propertyName)) {
				error("Multiple 'property' definitions for property '" + propertyName + "'", ele);
				return;
			}
			//parsePropertyValue前面有提到过，后面有详细介绍
			Object val = parsePropertyValue(ele, bd, propertyName);
			PropertyValue pv = new PropertyValue(propertyName, val);
			parseMetaElements(ele, pv);
			pv.setSource(extractSource(ele));
			//addPropertyValue前面有提到，后面有详细介绍
			bd.getPropertyValues().addPropertyValue(pv);
		}
		finally {
			this.parseState.pop();
		}
	}	



3.1.2 AbstractBeanDefinition属性


public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor
		implements BeanDefinition, Cloneable {



	private volatile Object beanClass;

	//bean的作用范围，对应bean属性scope
	private String scope = SCOPE_DEFAULT;

	//是否是抽象，对应bean属性abstract
	private boolean abstractFlag = false;

	//是否延迟加载，对应bean属性lazy-init
	private boolean lazyInit = false;

	//自动注入模式，对应bean属性autowire
	private int autowireMode = AUTOWIRE_NO;

	//依赖检查，Spring 3.0后弃用这个属性
	private int dependencyCheck = DEPENDENCY_CHECK_NONE;

	//用来表示一个bean的实例化依靠另一个bean先实例化，对应bean属性depend-on
	private String[] dependsOn;

	//autowire-candidate属性设置为false，这样容器在查找自动装配对象时，
	//将不考虑该bean，即它不会被考虑作为其他bean自动装配的候选者，但是该bean本身还是可以使用自动
	//装配来注入其他bean的。
	//对应bean属性autowire-candidate
	private boolean autowireCandidate = true;

	//自动装配时当出现多个bean候选者时，将作为首选者，对应bean属性primary
	private boolean primary = false;

	//用于记录Qualifier，对应子元素qualifier
	private final Map<String, AutowireCandidateQualifier> qualifiers =
			new LinkedHashMap<String, AutowireCandidateQualifier>(0);

	//允许访问非公开的构造器和方法，程序设置		
	private boolean nonPublicAccessAllowed = true;

	//是否以一种宽松的模式解析构造函数，默认为true，
	//如果为false，则在如下情况
	//抛出异常，因为Spring无法准确定位哪个构造函数
	//程序设置
	private boolean lenientConstructorResolution = true;

	//记录构造函数注入属性，对应bean属性constructor-arg
	private ConstructorArgumentValues constructorArgumentValues;

	//普通属性集合
	private MutablePropertyValues propertyValues;

	//方法重写的持有者，记录lookup-method,replaced-method元素
	private MethodOverrides methodOverrides = new MethodOverrides();
	
	/*
		对应bean属性factory-bean，用法：
		<bean id="instanceFactoryBean" class="example.chapter3.InstanceFactoryBean"/>
		<bean id="currentTime" factory-bean="instanceFactoryBean" factory-method="createTime"/>
	*/
	private String factoryBeanName;

	//对应bean属性factory-method
	private String factoryMethodName;

	//初始化方法，对应bean属性init-method
	private String initMethodName;

	//烧毁方法，对应bean属性destory-method
	private String destroyMethodName;

	//是否执行init-method，程序设置
	private boolean enforceInitMethod = true;

	//是否执行destory-method,程序设置
	private boolean enforceDestroyMethod = true;
	//是否是用户定义的而不是应用程序本身定义的，创建AOP时候为true，程序设置
	private boolean synthetic = false;

	//定义这个bean的应用，Application：用户，Infrastructure：完全内部使用，与用户无关，support：
	//某些复杂配置的一部分，程序设置
	private int role = BeanDefinition.ROLE_APPLICATION;

	//bean的描述信息
	private String description;

	//这个bean定义的资源
	private Resource resource;
	
	//set和get方法省略
}

3.1.3 解析默认标签中的自定义标签元素

类DefaultBeanDefinitionDocumentReader：
	protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
		//parseBeanDefinitionElement方法前面已有详细介绍
		BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
		if (bdHolder != null) {
			//decorateBeanDefinitionIfRequired方法后面有详细介绍
			bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
			try {
				// Register the final decorated instance.
				//registerBeanDefinition方法后面有详细介绍
				BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
			}
			catch (BeanDefinitionStoreException ex) {
				getReaderContext().error("Failed to register bean definition with name '" +
						bdHolder.getBeanName() + "'", ele, ex);
			}
			// Send registration event.
			//fireComponentRegistered方法后面有详细介绍
			//（当程序开发人员需要对注册BeanDefinition事件进行监听时可以通过注册监听器的方式
			//并将处理逻辑写入监听器中，目前Spring中并没有对此事件做任何逻辑处理）3.1.5 pdf
			getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
		}
	}
类BeanDefinitionParserDelegate：
	public BeanDefinitionHolder decorateBeanDefinitionIfRequired(Element ele, BeanDefinitionHolder definitionHolder) {
		//decorateBeanDefinitionIfRequired方法后面有详细介绍
		return decorateBeanDefinitionIfRequired(ele, definitionHolder, null);
	}

类BeanDefinitionParserDelegate：
	public BeanDefinitionHolder decorateBeanDefinitionIfRequired(
			Element ele, BeanDefinitionHolder definitionHolder, BeanDefinition containingBd) {

		//测试：finalDefinition：封装着GenericBean和Bean名字，Bean definition with name 'customer' and aliases []: Generic bean: class [com.dodi.spring.myLable.Customer]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in class path resource [myLable/defaultMybean.xml]	
		BeanDefinitionHolder finalDefinition = definitionHolder;

		// Decorate based on custom attributes first.
		//测试：attributes：封装着各属性[autowire="default", autowire-candidate="default", class="com.dodi.spring.myLable.Customer", id="customer", lazy-init="default"]
		NamedNodeMap attributes = ele.getAttributes();
		//（遍历所有的属性，看看是否有适用于修饰的属性）
		//根据属性的个数遍历
		for (int i = 0; i < attributes.getLength(); i++) {
			Node node = attributes.item(i);
			//decorateIfRequired方法后面有详细介绍
			finalDefinition = decorateIfRequired(node, finalDefinition, containingBd);
		}

		// Decorate based on custom nested elements.
		NodeList children = ele.getChildNodes();
		//（遍历所有的子节点，看看是否有适用于修饰的子元素）
		for (int i = 0; i < children.getLength(); i++) {
			Node node = children.item(i);
			if (node.getNodeType() == Node.ELEMENT_NODE) {
				//decorateIfRequired方法后面有详细介绍
				finalDefinition = decorateIfRequired(node, finalDefinition, containingBd);
			}
		}
		return finalDefinition;
	}

类BeanDefinitionParserDelegate：	
	public BeanDefinitionHolder decorateIfRequired(
			Node node, BeanDefinitionHolder originalDef, BeanDefinition containingBd) {

		//（获取自定义标签的命名空间）
		//测试：namespaceUri：null
		String namespaceUri = getNamespaceURI(node);
		//（对于非默认标签进行修饰）
		//下面判断没进，没找到测试案例
		if (!isDefaultNamespace(namespaceUri)) {
			//（根据命名空间找到对应的处理器）
			NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
			if (handler != null) {
				//（进行修饰）
				return handler.decorate(node, originalDef, new ParserContext(this.readerContext, this, containingBd));
			}
			else if (namespaceUri != null && namespaceUri.startsWith("http://www.springframework.org/")) {
				error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", node);
			}
			else {
				// A custom namespace, not to be handled by Spring - maybe "xml:...".
				if (logger.isDebugEnabled()) {
					logger.debug("No Spring NamespaceHandler found for XML schema namespace [" + namespaceUri + "]");
				}
			}
		}
		return originalDef;
	}


	
3.1.4 注册解析的BeanDefinition

类BeanDefinitionReaderUtils：
	public static void registerBeanDefinition(
			BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
			throws BeanDefinitionStoreException {

		// Register bean definition under primary name.
		//（使用beanName做唯一标识注册）
		String beanName = definitionHolder.getBeanName();
		//registerBeanDefinition方法后面有详细介绍    1.
		registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

		// Register aliases for bean name, if any.
		//（注册所有别名）
		String[] aliases = definitionHolder.getAliases();
		if (aliases != null) {
			for (String alias : aliases) {
				//registerAlias方法后面有详细介绍   2.
				registry.registerAlias(beanName, alias);
			}
		}
	}


	1. 通过beanName注册BeanDefinition

类DefaultListableBeanFactory：	
	public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
			throws BeanDefinitionStoreException {

		Assert.hasText(beanName, "Bean name must not be empty");
		Assert.notNull(beanDefinition, "BeanDefinition must not be null");

		if (beanDefinition instanceof AbstractBeanDefinition) {
			try {
				//（注册前的最后一次校验，这里的校验不同于之前的XML文件校验）
				//（主要是对于AbstractBeanDefinition属性中的methodOverrides校验）
				//（校验methodOverrides是否与工厂方法并存或者methodOverrides对应的方法根本不存在）
				//（1）
				((AbstractBeanDefinition) beanDefinition).validate();
			}
			catch (BeanDefinitionValidationException ex) {
				throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
						"Validation of bean definition failed", ex);
			}
		}

		BeanDefinition oldBeanDefinition;

		//测试：oldBeanDefinition：null
		oldBeanDefinition = this.beanDefinitionMap.get(beanName);
		//（处理注册已经注册的beanName情况）
		if (oldBeanDefinition != null) {
			//（如果对应的BeanName已经注册且在配置了bean不允许被覆盖，则抛出异常）
			//（2）
			if (!isAllowBeanDefinitionOverriding()) {
				throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
						"Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +
						"': There is already [" + oldBeanDefinition + "] bound.");
			}
			else if (oldBeanDefinition.getRole() < beanDefinition.getRole()) {
				// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
				if (this.logger.isWarnEnabled()) {
					this.logger.warn("Overriding user-defined bean definition for bean '" + beanName +
							"' with a framework-generated bean definition: replacing [" +
							oldBeanDefinition + "] with [" + beanDefinition + "]");
				}
			}
			else if (!beanDefinition.equals(oldBeanDefinition)) {
				if (this.logger.isInfoEnabled()) {
					this.logger.info("Overriding bean definition for bean '" + beanName +
							"' with a different definition: replacing [" + oldBeanDefinition +
							"] with [" + beanDefinition + "]");
				}
			}
			else {
				if (this.logger.isDebugEnabled()) {
					this.logger.debug("Overriding bean definition for bean '" + beanName +
							"' with an equivalent definition: replacing [" + oldBeanDefinition +
							"] with [" + beanDefinition + "]");
				}
			}
			//（注册beanDefinition）
			//（3）
			this.beanDefinitionMap.put(beanName, beanDefinition);
		}
		else {
			//测试：hasBeanCreationStarted()：false
			if (hasBeanCreationStarted()) {
				// Cannot modify startup-time collection elements anymore (for stable iteration)
				//（因为beanDefinitionMap是全局变量，这里定会存在并发访问的情况）
				synchronized (this.beanDefinitionMap) {
					this.beanDefinitionMap.put(beanName, beanDefinition);
					List<String> updatedDefinitions = new ArrayList<String>(this.beanDefinitionNames.size() + 1);
					updatedDefinitions.addAll(this.beanDefinitionNames);
					updatedDefinitions.add(beanName);
					this.beanDefinitionNames = updatedDefinitions;
					if (this.manualSingletonNames.contains(beanName)) {
						Set<String> updatedSingletons = new LinkedHashSet<String>(this.manualSingletonNames);
						updatedSingletons.remove(beanName);
						this.manualSingletonNames = updatedSingletons;
					}
				}
			}
			else {
				// Still in startup registration phase
				//（记录beanName）
				this.beanDefinitionMap.put(beanName, beanDefinition);
				this.beanDefinitionNames.add(beanName);
				this.manualSingletonNames.remove(beanName);
			}
			this.frozenBeanDefinitionNames = null;
		}

		//测试：没进入判断
		if (oldBeanDefinition != null || containsSingleton(beanName)) {
			//（重置所有beanName对应的缓存）
			//（4）
			resetBeanDefinition(beanName);
		}
	}
	
2. 通过别名注册BeanDefinition

类SimpleAliasRegistry：
	public void registerAlias(String name, String alias) {
		Assert.hasText(name, "'name' must not be empty");
		Assert.hasText(alias, "'alias' must not be empty");
		//（如果beanName与alias相同的话不记录alias，并删除对应的alias）
		//（1）
		if (alias.equals(name)) {
			this.aliasMap.remove(alias);
		}
		else {
			String registeredName = this.aliasMap.get(alias);
			if (registeredName != null) {
				if (registeredName.equals(name)) {
					// An existing alias - no need to re-register
					return;
				}
				//（如果alias不允许被覆盖则抛出异常）
				//（2）
				if (!allowAliasOverriding()) {
					throw new IllegalStateException("Cannot register alias '" + alias + "' for name '" +
							name + "': It is already registered for name '" + registeredName + "'.");
				}
			}
			//（当A->B存在时，若再次出现A->C->B时候则会抛出异常）
			//（3）
			checkForAliasCircle(name, alias);
			//（4）
			this.aliasMap.put(alias, name);
		}
	}	
	
3.1.5 通知监听器解析及注册完成	
	

3.2 alias标签的解析

类：	
	protected void processAliasRegistration(Element ele) {
		//（获取beanName）
		String name = ele.getAttribute(NAME_ATTRIBUTE);
		//（获取alias）
		String alias = ele.getAttribute(ALIAS_ATTRIBUTE);
		boolean valid = true;
		if (!StringUtils.hasText(name)) {
			getReaderContext().error("Name must not be empty", ele);
			valid = false;
		}
		if (!StringUtils.hasText(alias)) {
			getReaderContext().error("Alias must not be empty", ele);
			valid = false;
		}
		if (valid) {
			try {
				//（注册alias）
				getReaderContext().getRegistry().registerAlias(name, alias);
			}
			catch (Exception ex) {
				getReaderContext().error("Failed to register alias '" + alias +
						"' for bean with name '" + name + "'", ele, ex);
			}
			//（别名注册后通知监听器做相应处理）
			getReaderContext().fireAliasRegistered(name, alias, extractSource(ele));
		}
	}	
	
	
3.3 Import 标签的解析	
	
类DefaultBeanDefinitionDocumentReader：	
	protected void importBeanDefinitionResource(Element ele) {
		//（获取resource属性）
		//测试：location：applicationContext-user.xml
		//（1）
		String location = ele.getAttribute(RESOURCE_ATTRIBUTE);
		//（如果不存在resource属性则不做任何处理）
		if (!StringUtils.hasText(location)) {
			getReaderContext().error("Resource location must not be empty", ele);
			return;
		}

		// Resolve system properties: e.g. "${user.dir}"
		//（解析系统属性，格式如："${user.dir}"）
		//测试：location：applicationContext-user.xml
		//（2）
		location = getReaderContext().getEnvironment().resolveRequiredPlaceholders(location);

		Set<Resource> actualResources = new LinkedHashSet<Resource>(4);

		// Discover whether the location is an absolute or relative URI
		//（判定location是决定URI还是相对URI）
		//absoluteLocation：false
		//（3）
		boolean absoluteLocation = false;
		try {
			absoluteLocation = ResourcePatternUtils.isUrl(location) || ResourceUtils.toURI(location).isAbsolute();
		}
		catch (URISyntaxException ex) {
			// cannot convert to an URI, considering the location relative
			// unless it is the well-known Spring prefix "classpath*:"
		}

		// Absolute or relative?
		//（如果是绝对URI则直接根据地址加载对应的配置文件）
		//（4）
		if (absoluteLocation) {
			try {
				int importCount = getReaderContext().getReader().loadBeanDefinitions(location, actualResources);
				if (logger.isDebugEnabled()) {
					logger.debug("Imported " + importCount + " bean definitions from URL location [" + location + "]");
				}
			}
			catch (BeanDefinitionStoreException ex) {
				getReaderContext().error(
						"Failed to import bean definitions from URL location [" + location + "]", ele, ex);
			}
		}
		else {
			//（如果是相对地址则根据相对地址计算出绝对地址）
			//（5）
			// No URL -> considering resource location as relative to the current file.
			try {
				int importCount;
				//（Resource存在多个子实现类，如VfsResource、FileSystemResource等，）
				//（而每个resource的createRelative方式实现都不一样，所以这里先使用子类的方法尝试解析）
				//测试：relativeResource：class path resource [importTest/applicationContext-user.xml]
				Resource relativeResource = getReaderContext().getResource().createRelative(location);
				if (relativeResource.exists()) {
					//loadBeanDefinitions方法前面有详细说明，调用它解析import配置的文件
					importCount = getReaderContext().getReader().loadBeanDefinitions(relativeResource);
					//记录到Set集合actualResources中
					actualResources.add(relativeResource);
				}
				else {
					//（如果解析不成功，则使用默认的解析器ResourcePatternResolver进行解析）
					String baseLocation = getReaderContext().getResource().getURL().toString();
					importCount = getReaderContext().getReader().loadBeanDefinitions(
							StringUtils.applyRelativePath(baseLocation, location), actualResources);
				}
				if (logger.isDebugEnabled()) {
					logger.debug("Imported " + importCount + " bean definitions from relative location [" + location + "]");
				}
			}
			catch (IOException ex) {
				getReaderContext().error("Failed to resolve current resource location", ele, ex);
			}
			catch (BeanDefinitionStoreException ex) {
				getReaderContext().error("Failed to import bean definitions from relative location [" + location + "]",
						ele, ex);
			}
		}
		//（解析后进行监听器激活处理）
		//（6）
		Resource[] actResArray = actualResources.toArray(new Resource[actualResources.size()]);
		//程序员自己实现，spring没写逻辑
		getReaderContext().fireImportProcessed(location, actResArray, extractSource(ele));
	}	
	

3.4 嵌入式beans标签的解析

pdf无介绍，与其他解析差不多，自己探索。
	
	





第四章 自定义标签的解析

类DefaultBeanDefinitionDocumentReader：	
	protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
		//（对beans的处理）
		if (delegate.isDefaultNamespace(root)) {
			NodeList nl = root.getChildNodes();
			for (int i = 0; i < nl.getLength(); i++) {
				Node node = nl.item(i);
				if (node instanceof Element) {
					Element ele = (Element) node;
					//（对bean的处理）
					//猜：从字面的意思是默认Bean的解析
					if (delegate.isDefaultNamespace(ele)) {
						parseDefaultElement(ele, delegate);
					}
					else {
						//（对bean的处理）
						//猜：从字面的意思是用户自定义Bean的解析
						delegate.parseCustomElement(ele);
					}
				}
			}
		}
		else {
			//自定义标签的解析
			//parseCustomElement方法后面有详细介绍
			delegate.parseCustomElement(root);
		}
	}

4.1 自定义标签使用

类BeanDefinitionParserDelegate：	
	public BeanDefinition parseCustomElement(Element ele) {
		//parseCustomElement方法后面有详细介绍
		return parseCustomElement(ele, null);
	}

类BeanDefinitionParserDelegate：
	public BeanDefinition parseCustomElement(Element ele, BeanDefinition containingBd) {
		//（获取对应的命名空间）
		//测试：namespaceUri:http://www.wjs.com/schema/user
		//getNamespaceURI方法后面有详细介绍
		String namespaceUri = getNamespaceURI(ele);
		//（根据命名空间找到对应的NamespaceMandler）
		//getNamespaceHandlerResolver方法和resolve方法后面有详细介绍
		NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
		if (handler == null) {
			error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);
			return null;
		}
		//（调用自定义的NamespaceHandler进行解析）
		//parse方法后面有详细介绍
		return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
	}

4.2.1 获取标签的命名空间

类BeanDefinitionParserDelegate：
	public String getNamespaceURI(Node node) {
		//调用org.w3c.dom.Node中的方法获得
		return node.getNamespaceURI();
	}

4.2.2 提取自定义标签处理器

类DefaultNamespaceHandlerResolver：
	public NamespaceHandler resolve(String namespaceUri) {
		//（获取所有已经配置的handler映射）
		//getHandlerMappings方法后面有详细介绍
		//测试：handlerMappings：ConcurrentHashMap,{http://www.springframework.org/schema/aop=org.springframework.aop.config.AopNamespaceHandler, http://www.springframework.org/schema/task=org.springframework.scheduling.config.TaskNamespaceHandler, http://www.springframework.org/schema/lang=org.springframework.scripting.config.LangNamespaceHandler, http://www.wjs.com/schema/user=com.dodi.spring.myLable.MyUserNamespaceHandler, http://www.springframework.org/schema/c=org.springframework.beans.factory.xml.SimpleConstructorNamespaceHandler, http://www.springframework.org/schema/jee=org.springframework.ejb.config.JeeNamespaceHandler, http://www.springframework.org/schema/cache=org.springframework.cache.config.CacheNamespaceHandler, http://www.springframework.org/schema/jdbc=org.springframework.jdbc.config.JdbcNamespaceHandler, http://www.springframework.org/schema/p=org.springframework.beans.factory.xml.SimplePropertyNamespaceHandler, http://www.springframework.org/schema/util=org.springframework.beans.factory.xml.UtilNamespaceHandler, http://www.springframework.org/schema/tx=org.springframework.transaction.config.TxNamespaceHandler, http://www.springframework.org/schema/context=org.springframework.context.config.ContextNamespaceHandler}
		Map<String, Object> handlerMappings = getHandlerMappings();
		//（根据命名空间找到对应的信息）
		//从handlerMappings获得对应的NamespaceHandler
		//测试：handlerOrClassName：com.dodi.spring.myLable.MyUserNamespaceHandler
		Object handlerOrClassName = handlerMappings.get(namespaceUri);
		if (handlerOrClassName == null) {
			return null;
		}
		else if (handlerOrClassName instanceof NamespaceHandler) {
			//（已经做过解析的情况，直接从缓存读取）
			return (NamespaceHandler) handlerOrClassName;
		}
		else {
			//（没有做过解析，则返回的是类路径）
			String className = (String) handlerOrClassName;
			try {
				//（使用反射将类路径转化为类）
				//测试：handlerClass：class com.dodi.spring.myLable.MyUserNamespaceHandler
				Class<?> handlerClass = ClassUtils.forName(className, this.classLoader);
				//判断自定义bean的NamespaceHandler类是否为NamespaceHandler的子类，不是就抛异常，以前用过此反射方法
				if (!NamespaceHandler.class.isAssignableFrom(handlerClass)) {
					throw new FatalBeanException("Class [" + className + "] for namespace [" + namespaceUri +
							"] does not implement the [" + NamespaceHandler.class.getName() + "] interface");
				}
				//（初始化类）
				//实例化bean
				//测试：namespaceHandler：com.dodi.spring.myLable.MyUserNamespaceHandler@cd3fee8
				NamespaceHandler namespaceHandler = (NamespaceHandler) BeanUtils.instantiateClass(handlerClass);
				//（调用自定义的NamespaceHandler的初始化方法）
				//调用自定义处理器的初始化方法注册
				namespaceHandler.init();
				//（记录在缓存）
				handlerMappings.put(namespaceUri, namespaceHandler);
				return namespaceHandler;
			}
			catch (ClassNotFoundException ex) {
				throw new FatalBeanException("NamespaceHandler class [" + className + "] for namespace [" +
						namespaceUri + "] not found", ex);
			}
			catch (LinkageError err) {
				throw new FatalBeanException("Invalid NamespaceHandler class [" + className + "] for namespace [" +
						namespaceUri + "]: problem with handler class file or dependent class", err);
			}
		}
	}

类DefaultNamespaceHandlerResolver：	
	private Map<String, Object> getHandlerMappings() {
		//（如果没有被缓存则开始进行缓存）
		if (this.handlerMappings == null) {
			synchronized (this) {
				if (this.handlerMappings == null) {
					try {
						//（this.handlerMappingsLocation在构造函数中已经被初始化为：META-INF/Spring.handlers）
						//mappings：{http://www.springframework.org/schema/p=org.springframework.beans.factory.xml.SimplePropertyNamespaceHandler, http://www.springframework.org/schema/util=org.springframework.beans.factory.xml.UtilNamespaceHandler, http://www.wjs.com/schema/user=com.dodi.spring.myLable.MyUserNamespaceHandler, http://www.springframework.org/schema/jee=org.springframework.ejb.config.JeeNamespaceHandler, http://www.springframework.org/schema/aop=org.springframework.aop.config.AopNamespaceHandler, http://www.springframework.org/schema/jdbc=org.springframework.jdbc.config.JdbcNamespaceHandler, http://www.springframework.org/schema/cache=org.springframework.cache.config.CacheNamespaceHandler, http://www.springframework.org/schema/c=org.springframework.beans.factory.xml.SimpleConstructorNamespaceHandler, http://www.springframework.org/schema/tx=org.springframework.transaction.config.TxNamespaceHandler, http://www.springframework.org/schema/task=org.springframework.scheduling.config.TaskNamespaceHandler, http://www.springframework.org/schema/lang=org.springframework.scripting.config.LangNamespaceHandler, http://www.springframework.org/schema/context=org.springframework.context.config.ContextNamespaceHandler}
						//猜：通过PropertiesLoaderUtils.loadAllProperties方法获得所有nameSpaceHandel
						//PropertiesLoaderUtils.loadAllProperties方法具体不清楚
						Properties mappings =
								PropertiesLoaderUtils.loadAllProperties(this.handlerMappingsLocation, this.classLoader);
						if (logger.isDebugEnabled()) {
							logger.debug("Loaded NamespaceHandler mappings: " + mappings);
						}
						Map<String, Object> handlerMappings = new ConcurrentHashMap<String, Object>(mappings.size());
						//（将Properties格式文件合并到Map格式的handlerMapping中）
						CollectionUtils.mergePropertiesIntoMap(mappings, handlerMappings);
						this.handlerMappings = handlerMappings;
					}
					catch (IOException ex) {
						throw new IllegalStateException(
								"Unable to load NamespaceHandler mappings from location [" + this.handlerMappingsLocation + "]", ex);
					}
				}
			}
		}
		return this.handlerMappings;
	}

4.2.3 标签解析

类NamespaceHandlerSupport：
	public BeanDefinition parse(Element element, ParserContext parserContext) {
		//（寻找解析器并进行解析操作）
		//findParserForElement方法后面有详细解析
		return findParserForElement(element, parserContext).parse(element, parserContext);
	}

类NamespaceHandlerSupport：	
	private BeanDefinitionParser findParserForElement(Element element, ParserContext parserContext) {
		//（获取元素名称，也就是<myname:user中的user，若在示例中，此时localName为user）
		//测试：localName：user
		String localName = parserContext.getDelegate().getLocalName(element);
		//（根据user找到对应的解析器，也就是在
		//registerBeanDefinitionParser("user",new UserBeanDefinitionParser())
		//注册的解析器）
		//测试：parser：com.dodi.spring.myLable.UserBeanDefinitionParser@6e4784bc
		BeanDefinitionParser parser = this.parsers.get(localName);
		if (parser == null) {
			parserContext.getReaderContext().fatal(
					"Cannot locate BeanDefinitionParser for element [" + localName + "]", element);
		}
		return parser;
		
		
		
类AbstractBeanDefinitionParser：		
	public final BeanDefinition parse(Element element, ParserContext parserContext) {
		//parseInternal方法后面有详细介绍
		//测试：definition：GenericBeanDefinition，Generic bean: class [com.dodi.spring.myLable.User]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null
		AbstractBeanDefinition definition = parseInternal(element, parserContext);
		if (definition != null && !parserContext.isNested()) {
			try {
				//猜：获得自定义配置的id值
				//测试：id：testBean
				String id = resolveId(element, definition, parserContext);
				if (!StringUtils.hasText(id)) {
					parserContext.getReaderContext().error(
							"Id is required for element '" + parserContext.getDelegate().getLocalName(element)
									+ "' when used as a top-level tag", element);
				}
				String[] aliases = null;
				//shouldParseNameAsAliases方法：直接返回true的方法，不清楚这样做目的
				//猜：判断是对name属性的处理
				if (shouldParseNameAsAliases()) {
					String name = element.getAttribute(NAME_ATTRIBUTE);
					if (StringUtils.hasLength(name)) {
						aliases = StringUtils.trimArrayElements(StringUtils.commaDelimitedListToStringArray(name));
					}
				}
				//（将AbstractBeanDefinition转换为BeanDefinitionHolder并注册）
				//猜：AbstractBeanDefinition转换为BeanDefinitionHolder
				BeanDefinitionHolder holder = new BeanDefinitionHolder(definition, id, aliases);
				//猜：注册holder
				registerBeanDefinition(holder, parserContext.getRegistry());
				//shouldFireEvents方法，直接返回true的方法，不清楚这样做目的
				if (shouldFireEvents()) {
					//（需要通知监听器则进行处理）
					BeanComponentDefinition componentDefinition = new BeanComponentDefinition(holder);
					//postProcessComponentDefinition方法为空方法，可能是代用户拓展的方法，前面有遇到过此类型方法
					postProcessComponentDefinition(componentDefinition);
					//registerComponent方法不清楚
					parserContext.registerComponent(componentDefinition);
				}
			}
			catch (BeanDefinitionStoreException ex) {
				parserContext.getReaderContext().error(ex.getMessage(), element);
				return null;
			}
		}
		return definition;
	}
	}	

	protected final AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
		//看：创建新对象BeanDefinitionBuilder，GenericBeanDefinition并封装到builder		
		BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition();
		//猜：获得父Bean的name
		//测试：parentName：null
		String parentName = getParentName(element);
		if (parentName != null) {
			builder.getRawBeanDefinition().setParentName(parentName);
		}
		//（获取自定义标签中的class，此时会调用自定义解析器如UserBeanDefinitionParser中的getBeanClass方法）
		//beanClass：class com.dodi.spring.myLable.User
		//自定义的UserBeanDefinitionParser重写的getBeanClass方法。
		Class<?> beanClass = getBeanClass(element);
		if (beanClass != null) {
			builder.getRawBeanDefinition().setBeanClass(beanClass);
		}
		else {
			//（若子类没有重写getBeanClass方法则尝试检查子类是否重写getBeanClassName方法）
			String beanClassName = getBeanClassName(element);
			if (beanClassName != null) {
				builder.getRawBeanDefinition().setBeanClassName(beanClassName);
			}
		}
		//以下这行代码不清楚
		builder.getRawBeanDefinition().setSource(parserContext.extractSource(element));
		if (parserContext.isNested()) {
			// Inner bean definition must receive same scope as containing bean.
			//（若存在父类则使用父类的scope属性）
			builder.setScope(parserContext.getContainingBeanDefinition().getScope());
		}
		if (parserContext.isDefaultLazyInit()) {
			// Default-lazy-init applies to custom bean definitions as well.
			//（配置延迟加载）
			builder.setLazyInit(true);
		}
		//（调用子类重写的doParse方法进行解析）
		//doParse方法后面有详细介绍
		doParse(element, parserContext, builder);
		return builder.getBeanDefinition();
	}
	
	
	



第五章 bean的加载



1.	类AbstractBeanFactory:
	@Override
	public Object getBean(String name) throws BeansException {
		return doGetBean(name, null, null, false);
	}
	

2.	类·AbstractBeanFactory:
		@SuppressWarnings("unchecked")
	protected <T> T doGetBean(
			final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
			throws BeansException {

		//（提取对应的beanname）
		//transformedBeanName不清楚
		//猜：在spring配置文件中的id值。
		//测试:user
		//（1）
		final String beanName = transformedBeanName(name);
		Object bean;

		//（直接尝试从缓存获取或者singletonFactories中的ObjectFactory中获取）
		//猜:获取的应该是spring帮我们创建的放在缓存对象。
		//测试：第一次中为null
		//后续：getSingleton方法有进一步介绍（5.2节）
		//（2）
		Object sharedInstance = getSingleton(beanName);
		//判断获取到的实例是否为空
		//args 为null,猜：调用getBean中的重载方法，调用传参为null。
		if (sharedInstance != null && args == null) {
			if (logger.isDebugEnabled()) {
				//<不重要，判断只是生成log>
				//猜：isSingletonCurrentlyInCreation(beanName)判断beanName的bean是否已经初始化，true为没被初始化，写进log信息。				
				if (isSingletonCurrentlyInCreation(beanName)) {
					logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
							"' that is not fully initialized yet - a consequence of a circular reference");
				}
				else {
					logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
				}
			}
			//(返回对应的实例． 有时候存在诸如 Beanfact。町的悄况并不是直接返回实例本身而是返回指定方法返回的实例)
			//后续：getObjectForBeanInstance方法有进一步介绍（5.3节）
			//（3）
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}

		else {
			// Fail if we're already creating this bean instance:
			// We're assumably within a circular reference.
			//(只有在单例情况才会尝试解决循环依赖． 原利模式情况下， 如果存在)
			//(且中有B的属性• B中有R的属性． 那么当依赖注入的时候． 就会产生当且还未鱼饵搅(J(Jff.t自主因为,对于B的创建再次返回创建A， 造成循环依赖， 也就是下面的俯况)
			//(isProt。typeCurrentlylnCreati。n(beanName）为true)
			//不清楚：isPrototypeCurrentlyInCreation方法
			//（4）
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}


			// Check if bean definition exists in this factory.
			//猜：获得父对象工厂，待自己进一步看看。
			//测试：为null
			//（5）
			BeanFactory parentBeanFactory = getParentBeanFactory();
			//(如果beanDefinitiorMap 中也就是在所有已经加娥的类中不包括 beanName 则尝试从parentBeanFactory中检测)
			//containsBeanDefinition待自己进一步看看。
			//（containsBeanDefinition检测当前加载的xml配置文件中不包含beanName所对应配置）
			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
				// Not found -> check parent.
				String nameToLookup = originalBeanName(name);
				//(递归到BeanFactory中寻找)
				if (args != null) {
					// Delegation to parent with explicit args.
					//parentBeanFactory.getBean待自己进一步看看。分通过args参数和requiredType参数获得两种。
					return (T) parentBeanFactory.getBean(nameToLookup, args);
				}
				else {
					// No args -> delegate to standard getBean method.
					return parentBeanFactory.getBean(nameToLookup, requiredType);
				}
			}
			//（如果不是仅仅做类型检查则是创建bean，这里要进行记录）
			//猜：记录bean的信息
			//测试：第一次是会执行这方法
			if (!typeCheckOnly) {
				markBeanAsCreated(beanName);
			}

			try {
				//（将存储xml配置文件的GernericBeanDefinition转换为RootBeanDefinition，）
				//（如果指定BeanName是子Bean的话同时会合并父类的相关属性）
				//测试：mbd：（Root bean: class [com.dodi.spring.pojo.User]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in class path resource [applicationContext.xml]）
				//getMergedLocalBeanDefinition方法不清楚
				//（6）
				final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				//checkMergedBeanDefinition方法不清楚
				checkMergedBeanDefinition(mbd, beanName, args);

				// Guarantee initialization of beans that the current bean depends on.
				//若存在依赖则需要递归实例化bean
				//（7）
				String[] dependsOn = mbd.getDependsOn();
				if (dependsOn != null) {
					for (String dependsOnBean : dependsOn) {
						//猜：isDependent方法判断是否死循环依赖，是抛异常
						if (isDependent(beanName, dependsOnBean)) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"Circular depends-on relationship between '" + beanName + "' and '" + dependsOnBean + "'");
						}
						//缓存依赖调用
						registerDependentBean(dependsOnBean, beanName);
						getBean(dependsOnBean);
					}
				}

				// Create bean instance.
				//（实例化依赖的bean后便可以实例化mbd本身了）
				//（singleton模式的创建）------------------------------
				//（8）
				if (mbd.isSingleton()) {
					//getSingleton方法后面有详细解析（5.4节）
					sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
						@Override
						public Object getObject() throws BeansException {
							try {
								//createBean方法后面有详细解析（5.5节）
								return createBean(beanName, mbd, args);
							}
							catch (BeansException ex) {
								// Explicitly remove instance from singleton cache: It might have been put there
								// eagerly by the creation process, to allow for circular reference resolution.
								// Also remove any beans that received a temporary reference to the bean.
								destroySingleton(beanName);
								throw ex;
							}
						}
					});
					//getObjectForBeanInstance方法后面有详细解析（5.3节）
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}
				//多例模式创建---------------
				else if (mbd.isPrototype()) {
					// It's a prototype -> create a new instance.
					Object prototypeInstance = null;
					try {
						//beforePrototypeCreation方法不清楚
						//猜：多例创建的前处理
						beforePrototypeCreation(beanName);
						//createBean方法后面有详细解析
						prototypeInstance = createBean(beanName, mbd, args);
					}
					finally {
						//afterPrototypeCreation方法不清楚
						//猜：多例创建的前处理
						afterPrototypeCreation(beanName);
					}
					//getObjectForBeanInstance方法后面有详细解析
					bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
				}

				else {
					//指定的scope上的bean创建
					String scopeName = mbd.getScope();
					final Scope scope = this.scopes.get(scopeName);
					if (scope == null) {
						throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
					}
					try {
						//scope的get方法与单例的getSingleton方法类似，比对一下
						Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
							@Override
							public Object getObject() throws BeansException {
								//上面的多例前处理方法
								beforePrototypeCreation(beanName);
								try {
									return createBean(beanName, mbd, args);
								}
								finally {
									//上面的多例后处理方法
									afterPrototypeCreation(beanName);
								}
							}
						});
						//getObjectForBeanInstance方法后面有详细解析
						bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
					}
					catch (IllegalStateException ex) {
						throw new BeanCreationException(beanName,
								"Scope '" + scopeName + "' is not active for the current thread; consider " +
								"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
								ex);
					}
				}
			}
			catch (BeansException ex) {
				cleanupAfterBeanCreationFailure(beanName);
				throw ex;
			}
		}

		// Check if required type matches the type of the actual bean instance.
		//（检查需要的类型是否符合bean的实际类型）
		//（9）
		if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
			try {
				//getTypeConverter().convertIfNecessary不清楚
				return getTypeConverter().convertIfNecessary(bean, requiredType);
			}
			catch (TypeMismatchException ex) {
				if (logger.isDebugEnabled()) {
					logger.debug("Failed to convert bean '" + name + "' to required type [" +
							ClassUtils.getQualifiedName(requiredType) + "]", ex);
				}
				throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
			}
		}
		return (T) bean;
	}
	
	
5.1	FactoryBean的使用

	//使用场景较小：当<bean>的class属性配置的实现类是FactoryBean时，
	//通过getBean()方法返回的不是FactoryBean本身，而是FactoryBean#getObject()
	//方法返回的对象，相当于FactoryBean#getObject()代理了getBean（）方法。
	public interface FactoryBean<T> {

		//（返回由FactoryBean创建的bean实例，如果isSingleton()返回true，）
		//（则该实例会放到Spring容器中单实例池中）
		T getObject() throws Exception;
		//返回FactoryBean创建的bean类型。
		Class<?> getObjectType();
		//返回由FactoryBean创建的bean实例的作用域是singleton还是prototype
		boolean isSingleton();

	}

	例子见代码。
	

5.2缓存中获取单例bean

类DefaultSingletonBeanRegistry：
	public Object getSingleton(String beanName) {
		//参数true设置标识允许早期依赖
		return getSingleton(beanName, true);
	}
	
类DefaultSingletonBeanRegistry：
	protected Object getSingleton(String beanName, boolean allowEarlyReference) {
		//（检查缓存中是否存在实例）
		Object singletonObject = this.singletonObjects.get(beanName);
		//isSingletonCurrentlyInCreation方法不清楚
		//测试：首次单例时，singletonObject为null，isSingletonCurrentlyInCreation(beanName)为false
		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
			//（如果为空，则锁定全局变量并进行处理）
			synchronized (this.singletonObjects) {
				//（如果此bean正在加载则不处理）
				//earlySingletonObjects.get方法不清楚
				singletonObject = this.earlySingletonObjects.get(beanName);
				//allowEarlyReference为true时允许早期依赖
				if (singletonObject == null && allowEarlyReference) {
					//（当某些方法需要提前初始化的时候则会调用addSingletonFactory方法）
					//（将对应的ObjectFactory初始化策略存储在singletonFactories）
					//singletonFactories.get(beanName)方法不清楚
					//猜：从当前bean的beanFactories（map）中获取自己的ObjectFactory
					ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
					if (singletonFactory != null) {
						//（调用预先设定的getObject方法）
						singletonObject = singletonFactory.getObject();
						//（记录在缓存中，earlySingletonObject和singleFactoies互斥）
						this.earlySingletonObjects.put(beanName, singletonObject);
						this.singletonFactories.remove(beanName);
					}
				}
			}
		}
		return (singletonObject != NULL_OBJECT ? singletonObject : null);
	}	
	/*
		不同map的作用：
		singletonObjects：用于保存BeanName和创建bean实例之间的关系，beanName-->beanInstance
		singletonFactories：用于保存BeanName和创建bean的工厂之间的关系，beanName-->ObjectFactory
		earlySingletonObjects：也是保存BeanName和创建bean的工厂之间的关系，与singletonObjects的不同之处在于，
		当一个单例bean被放到里面后，那么当bean还在创建过程中，就可以通过getBean方法获取到了，其目的时用来检查循环引用。
		registeredSingletons：用来保存当前所有已注册的bean
	*/
	
5.3从bean的实例中获取对象
	
	类AbstractBeanFactory：
		protected Object getObjectForBeanInstance(
			Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {

		//（如果指定的name是工厂相关(以&为前缀)且beanInstance又不是Factory类型则验证不通过）
		//猜：工厂bean的测试
		//测试：BeanFactoryUtils.isFactoryDereference(name)为false，!(beanInstance instanceof FactoryBean)为true，不是工厂类
		if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
			throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
		}

		//（现在我们有了个bean的实例，这个实例可能会是正常的bean或者是FactoryBean）
		//（如果是FactoryBean我们使用它创建实例，但是如果用户想要直接获取工厂实例而不是）
		//（工厂的getObject方法对应的实例那么传入的name应该加入前缀）
		//测试：!(beanInstance instanceof FactoryBean)为true，是正常bean，BeanFactoryUtils.isFactoryDereference(name)为false，不是工厂相关（不是&的前缀）
		if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
			return beanInstance;
		}
		//加载FactoryBean
		Object object = null;
		if (mbd == null) {
			//尝试从缓存中加载bean，传入的mbd为null
			//getCachedObjectForFactoryBean方法不清楚
			object = getCachedObjectForFactoryBean(beanName);
		}
		if (object == null) {
			// Return bean instance from factory.
			//（到这里已经明确知道beanInstance一定是FactoryBean类型）
			FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
			// Caches object obtained from FactoryBean if it is a singleton.
			//（containsBeanDefinition检测beanDefinitionMap中也就是在所有已经）
			//（加载的类中检测是否定义beanName）
			//containsBeanDefinition方法具体不清楚
			if (mbd == null && containsBeanDefinition(beanName)) {
				//（将存储XML配置文件的GernericBeanDefinition转换为RootBeanDefinition，如果）
				//（指定BeanName是子Bean的话同时会合并父类的相关属性）
				//测试：mbd：[com.dodi.spring.factoryBean.CarFactoryBean]
				//getMergedLocalBeanDefinition具体不清楚
				mbd = getMergedLocalBeanDefinition(beanName);
			}
			//（是否是用户定义的而不是应用程序本身定义的）
			boolean synthetic = (mbd != null && mbd.isSynthetic());
			//猜：getObjectFromFactoryBean方法调用getObject方法获得对象
			//getObjectFromFactoryBean方法后面有详细介绍
			object = getObjectFromFactoryBean(factory, beanName, !synthetic);
		}
		return object;
	}

	类FactoryBeanRegistrySupport：
	
	protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
		//（如果是单例模式）
		if (factory.isSingleton() && containsSingleton(beanName)) {
			//getSingletonMutex()方法返回锁对象为父类DefaultSingletonBeanRegistry的map集合singletonObjects
			synchronized (getSingletonMutex()) {
				//factoryBeanObjectCache.get方法不清楚
				Object object = this.factoryBeanObjectCache.get(beanName);
				if (object == null) {
					//doGetObjectFromFactoryBean方法后面有详细介绍
					object = doGetObjectFromFactoryBean(factory, beanName);
					// Only post-process and store if not put there already during getObject() call above
					// (e.g. because of circular reference processing triggered by custom getBean calls)
					//factoryBeanObjectCache.get方法与前面一样，不清楚
					Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
					if (alreadyThere != null) {
						object = alreadyThere;
					}
					else {
						//shouldPostProcess为参数
						if (object != null && shouldPostProcess) {
							try {
								//postProcessObjectFromFactoryBean后面有详细介绍
								object = postProcessObjectFromFactoryBean(object, beanName);
							}
							catch (Throwable ex) {
								throw new BeanCreationException(beanName,
										"Post-processing of FactoryBean's singleton object failed", ex);
							}
						}
						//放入缓存中
						this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));
					}
				}
				return (object != NULL_OBJECT ? object : null);
			}
		}
		else {
			//doGetObjectFromFactoryBean与上面方法一样，后面有详细介绍
			Object object = doGetObjectFromFactoryBean(factory, beanName);
			if (object != null && shouldPostProcess) {
				try {
					//postProcessObjectFromFactoryBean方法与前面一样，后面有详细介绍
					object = postProcessObjectFromFactoryBean(object, beanName);
				}
				catch (Throwable ex) {
					throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
				}
			}
			return object;
		}
	}

	
	类FactoryBeanRegistrySupport：
	private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
			throws BeanCreationException {

		Object object;
		try {
			//（需要权限验证）
			//getSecurityManager方法不清楚
			//以下if为权限验证代码，测试时没进入，以后再看
			if (System.getSecurityManager() != null) {
				AccessControlContext acc = getAccessControlContext();
				try {
					object = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
						@Override
						public Object run() throws Exception {
								return factory.getObject();
							}
						}, acc);
				}
				catch (PrivilegedActionException pae) {
					throw pae.getException();
				}
			}
			else {
				//（直接调用getObject方法）
				//猜：调用的重写的getObject方法。
				object = factory.getObject();
			}
		}
		catch (FactoryBeanNotInitializedException ex) {
			throw new BeanCurrentlyInCreationException(beanName, ex.toString());
		}
		catch (Throwable ex) {
			throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
		}

		// Do not accept a null value for a FactoryBean that's not fully
		// initialized yet: Many FactoryBeans just return null then.
		if (object == null && isSingletonCurrentlyInCreation(beanName)) {
			throw new BeanCurrentlyInCreationException(
					beanName, "FactoryBean which is currently in creation returned null from getObject");
		}
		return object;
	}	
	
	类AbstractAutowireCapableBeanFactory：
		protected Object postProcessObjectFromFactoryBean(Object object, String beanName) {
		return applyBeanPostProcessorsAfterInitialization(object, beanName);
	}
	
	类AbstractAutowireCapableBeanFactory：
		
		public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException {

		Object result = existingBean;
		for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
			//（所有bean初始化后都会调用这方法postProcessAfterInitialization进行处理，
			//这样可以针对此特性设计自己的业务逻辑）
			//这后处理器后面章节有具体介绍
			result = beanProcessor.postProcessAfterInitialization(result, beanName);
			if (result == null) {
				return result;
			}
		}
		return result;
	}
	
5.4获取单例	
	类DefaultSingletonBeanRegistry：
	public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
		Assert.notNull(beanName, "'beanName' must not be null");
		//（全局变量需要同步）
		synchronized (this.singletonObjects) {
			//（首先检查对应的bean是否已经加载过，因为singleton模式其实就是复用已
			//创建的bean，所以这一步是必须的）
			//尝试从map集合singletonObjects中获得当前bean
			//（1）
			Object singletonObject = this.singletonObjects.get(beanName);
			//（如果为空才可以进行singleton的bean的初始化）
			if (singletonObject == null) {
				//singletonsCurrentlyInDestruction参数初始化为false
				if (this.singletonsCurrentlyInDestruction) {
					throw new BeanCreationNotAllowedException(beanName,
							"Singleton bean creation not allowed while the singletons of this factory are in destruction " +
							"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
				}
				if (logger.isDebugEnabled()) {
					logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
				}
				//beforeSingletonCreation方法后面有详细介绍
				//猜：单例bean创建的前处理
				//（2）（3）
				beforeSingletonCreation(beanName);
				boolean newSingleton = false;
				//猜：suppressedExceptions为set集合，从字面理解是存放异常的
				boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
				if (recordSuppressedExceptions) {
					this.suppressedExceptions = new LinkedHashSet<Exception>();
				}
				try {
					//（初始化bean）
					//singletonFactory为传进参数，为匿名内部类创建的singletonFactory
					//（4）（7）
					singletonObject = singletonFactory.getObject();
					newSingleton = true;
				}
				catch (IllegalStateException ex) {
					// Has the singleton object implicitly appeared in the meantime ->
					// if yes, proceed with it since the exception indicates that state.
					//前面有用过，尝试从map集合singletonObjects中获得当前bean
					singletonObject = this.singletonObjects.get(beanName);
					if (singletonObject == null) {
						throw ex;
					}
				}
				catch (BeanCreationException ex) {
					if (recordSuppressedExceptions) {
						for (Exception suppressedException : this.suppressedExceptions) {
							ex.addRelatedCause(suppressedException);
						}
					}
					throw ex;
				}
				finally {
					if (recordSuppressedExceptions) {
						this.suppressedExceptions = null;
					}
					//afterSingletonCreation方法后面有详细介绍
					//猜：单例bean创建的后处理
					//（5）
					afterSingletonCreation(beanName);
				}
				if (newSingleton) {
					//（加入缓存）
					//addSingleton方法后面有详细介绍
					//（6）
					addSingleton(beanName, singletonObject);
				}
			}
			return (singletonObject != NULL_OBJECT ? singletonObject : null);
		}
	}

类DefaultSingletonBeanRegistry：	
	protected void beforeSingletonCreation(String beanName) {
		//猜：this.inCreationCheckExclusions.contains(beanName)判断上面的set集合inCreationCheckExclusions
		//中是否有该bean，this.singletonsCurrentlyInCreation.add(beanName)把该bean加入到set集合
		//singletonsCurrentlyInCreation中，（这样便可以对循环依赖进行检测）
		if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
			throw new BeanCurrentlyInCreationException(beanName);
		}
	}	
类DefaultSingletonBeanRegistry：	
	protected void afterSingletonCreation(String beanName) {
		//当bean加载结束后需要移除缓存中对该bean的正在加载状态记录（set集合singletonsCurrentlyInCreation中）
		if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
			throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
		}
	}
类DefaultSingletonBeanRegistry：
	//将结果记录至缓存并删除加载bean过程中所记录的各种辅助状态
	protected void addSingleton(String beanName, Object singletonObject) {
		synchronized (this.singletonObjects) {
			//各map的作用参照5.2节的介绍
			this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT));
			this.singletonFactories.remove(beanName);
			this.earlySingletonObjects.remove(beanName);
			this.registeredSingletons.add(beanName);
		}
	}
类AbstractBeanFactory：
	sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
		@Override
		public Object getObject() throws BeansException {
			try {
				//创建bean的核心方法（5.5节）
				return createBean(beanName, mbd, args);
			}
			catch (BeansException ex) {
				destroySingleton(beanName);
				throw ex;
			}
		}
	}
	
5.5 准备创建bean	

	protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
		if (logger.isDebugEnabled()) {
			logger.debug("Creating instance of bean '" + beanName + "'");
		}
		RootBeanDefinition mbdToUse = mbd;

		// Make sure bean class is actually resolved at this point, and
		// clone the bean definition in case of a dynamically resolved Class
		// which cannot be stored in the shared merged bean definition.
		//（resolveBeanClass方法锁定class，根据设置的class属性或者根据className来解析Class）
		//resolveBeanClass方法不清楚
		//测试：resolvedClass：class com.dodi.spring.pojo.User
		//（1）
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		//猜：mbd中没有当前RootBeanDefinition时，创建该RootBeanDefinition并放进去
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		}

		// Prepare method overrides.
		//（验证及准备覆盖的方法）
		//mbdToUse.prepareMethodOverrides()方法后面有详细介绍
		//（2）（5.5.1节）
		try {
			mbdToUse.prepareMethodOverrides();
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
					beanName, "Validation of method overrides failed", ex);
		}

		try {
			// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
			//（给BeanPostProcessors一个机会返回代理来替代真正的实例）
			//resolveBeforeInstantiation方法后面有详细介绍
			//（3）
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			if (bean != null) {
				return bean;
			}
		}
		catch (Throwable ex) {
			throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
					"BeanPostProcessor before instantiation of bean failed", ex);
		}
		//doCreateBean方法后面有详细介绍
		//（4）
		Object beanInstance = doCreateBean(beanName, mbdToUse, args);
		if (logger.isDebugEnabled()) {
			logger.debug("Finished creating instance of bean '" + beanName + "'");
		}
		return beanInstance;
	}
5.5.1 处理override属性	
类AbstractBeanDefinition：
	public void prepareMethodOverrides() throws BeanDefinitionValidationException {
		// Check that lookup methods exists.
		//猜：检查是否有覆盖的方法
		MethodOverrides methodOverrides = getMethodOverrides();
		if (!methodOverrides.isEmpty()) {
			for (MethodOverride mo : methodOverrides.getOverrides()) {
				//prepareMethodOverride后面有详细介绍
				prepareMethodOverride(mo);
			}
		}
	}
	
类AbstractBeanDefinition：
	protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException {
		//（获取对应类中对应方法名的个数）
		//getMethodCountForName方法具体不清楚
		int count = ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName());
		if (count == 0) {
			throw new BeanDefinitionValidationException(
					"Invalid method override: no method with name '" + mo.getMethodName() +
					"' on class [" + getBeanClassName() + "]");
		}
		else if (count == 1) {
			// Mark override as not overloaded, to avoid the overhead of arg type checking.
			//（标记MethodOverride暂未被覆盖，避免参数类型检查的开销）
			mo.setOverloaded(false);
		}
	}
	
5.5.2 实例化的前置处理（AOP功能）
类AbstractAutowireCapableBeanFactory：
	protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
		Object bean = null;
		//（如果尚未被解析）
		if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
			// Make sure bean class is actually resolved at this point.
			//mbd.isSynthetic方法不清楚，前面有用到
			//hasInstantiationAwareBeanPostProcessors方法不清楚
			if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
				Class<?> targetType = determineTargetType(beanName, mbd);
				if (targetType != null) {
					//applyBeanPostProcessorsBeforeInstantiation方法后面有详细介绍
					bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
					if (bean != null) {
					//applyBeanPostProcessorsAfterInitialization方法后面有详细介绍	
						bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
					}
				}
			}
			mbd.beforeInstantiationResolved = (bean != null);
		}
		return bean;
	}
1. 实例化前的后处理器应用
	//第7章会详细介绍
类AbstractAutowireCapableBeanFactory：	
	protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName)
			throws BeansException {

		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof InstantiationAwareBeanPostProcessor) {
				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
				Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
				if (result != null) {
					return result;
				}
			}
		}
		return null;
	}

2. 实例化后的后处理器应用	
类AbstractAutowireCapableBeanFactory：
//创建单例bean时，bean应尽可能应用方法postProcessAfterInitialization，如果
//返回bean不为空，那么便不会经历普通bean的创建过程，只能应用这方法调用。
	public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException {

		Object result = existingBean;
		for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
			result = beanProcessor.postProcessAfterInitialization(result, beanName);
			if (result == null) {
				return result;
			}
		}
		return result;
	}	
	
5.6	循环依赖

类AbstractAutowireCapableBeanFactory：
			addSingletonFactory(beanName, new ObjectFactory<Object>() {
				@Override
				public Object getObject() throws BeansException {
					return getEarlyBeanReference(beanName, mbd, bean);
				}
			});

5.7 创建bean
类AbstractAutowireCapableBeanFactory：
	protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
		// Instantiate the bean.
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			//猜：如果当前bean是单例，移除map集合factoryBeanInstanceCache中的当前bean
			//（1）
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			//（根据指定bean使用对应的策略创建新的实例，如：工厂方法、构造函数自动注入、简单初始化）
			//createBeanInstance后面有详细介绍（5.7.1节）
			//（2）
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		//测试：instanceWrapper.getWrappedInstance()：为当前对象User [uid=null, name=null, city=null]
		final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
		//测试：instanceWrapper.getWrappedClass()：为当前对象的字节码对象class com.dodi.spring.pojo.User
		Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);

		// Allow post-processors to modify the merged bean definition.
		//锁对象为RootBeanDefinition中的常量对象postProcessingLock
		synchronized (mbd.postProcessingLock) {
			//单词为是否已经后处理
			if (!mbd.postProcessed) {
				//应用MergedBeanDefinitionPostProcessor
				//applyMergedBeanDefinitionPostProcessors不清楚
				//（3）
				applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				mbd.postProcessed = true;
			}
		}

		//（是否需要提早曝光：单例&允许循环依赖&当前bean正在创建中，检测循环依赖）《标志黑色》
		//isSingleton，isSingletonCurrentlyInCreation方法具体不清楚
		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
				isSingletonCurrentlyInCreation(beanName));
		if (earlySingletonExposure) {
			if (logger.isDebugEnabled()) {
				logger.debug("Eagerly caching bean '" + beanName +
						"' to allow for resolving potential circular references");
			}
			//（为避免后期循环依赖，可以在bean初始化完成前将创建实例的ObjectFactory加入工厂）
			//addSingletonFactory具体不清楚
			//（4）
			addSingletonFactory(beanName, new ObjectFactory<Object>() {
				@Override
				public Object getObject() throws BeansException {
					//（对bean再一次依赖引用，主要应用SmartInstantiationAware BeanPostProcessor）
					//（其中我们熟知的AOP就是在这里将advice动态织入bean中，若没有则直接返回bean，不做任何处理）
					//getEarlyBeanReference不清楚
					return getEarlyBeanReference(beanName, mbd, bean);
				}
			});
		}

		// Initialize the bean instance.
		Object exposedObject = bean;
		try {
			//（对bean进行填充，将各个属性值注入，其中，可能存在依赖于其他bean的属性，则会递归初始依赖bean）
			//populateBean方法后面有详细介绍
			//（5）
			populateBean(beanName, mbd, instanceWrapper);
			if (exposedObject != null) {
				//（调用初始化方法，比如init-method）
				//initializeBean方法后面有详细介绍
				exposedObject = initializeBean(beanName, exposedObject, mbd);
			}
		}
		catch (Throwable ex) {
			if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
				throw (BeanCreationException) ex;
			}
			else {
				throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
			}
		}

		if (earlySingletonExposure) {
			//getSingleton方法前面有介绍
			//猜：获得map集合中获得earlySingletonReference对象
			Object earlySingletonReference = getSingleton(beanName, false);
			//（earlySingletonReference只有在检测到有循环依赖的情况下才会不为空）
			if (earlySingletonReference != null) {
				//（如果exposedObject没有在初始化方法中被改变，也就是没有被增强）
				if (exposedObject == bean) {
					exposedObject = earlySingletonReference;
				}
				//成员变量和hasDependentBean方法具体不清楚
				else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
					//猜：从代码看，是从map集合dependentBeanMap获得的当前bean依赖
					//getDependentBeans方法不清楚
					String[] dependentBeans = getDependentBeans(beanName);
					Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
					for (String dependentBean : dependentBeans) {
						//（检测依赖）
						//removeSingletonIfCreatedForTypeCheckOnly方法不清楚
						//（6）
						if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
							actualDependentBeans.add(dependentBean);
						}
					}
					//（因为bean创建后其所依赖的bean一定是已经创建的，actualDependentBeans不为空
					//则表示当前bean创建后其依赖的bean却没有，没全部创建完，也就是说存在循环依赖）
					if (!actualDependentBeans.isEmpty()) {
						throw new BeanCurrentlyInCreationException(beanName,
								"Bean with name '" + beanName + "' has been injected into other beans [" +
								StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
								"] in its raw version as part of a circular reference, but has eventually been " +
								"wrapped. This means that said other beans do not use the final version of the " +
								"bean. This is often the result of over-eager type matching - consider using " +
								"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
					}
				}
			}
		}

		// Register bean as disposable.
		try {
			//（根据scope注册bean）
			//registerDisposableBeanIfNecessary后面有详细介绍 5.7.5节
			//（7）
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
		}

		//（8）
		return exposedObject;
	}
	
5.7.1 创建bean的实例

	protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
		// Make sure bean class is actually resolved at this point.
		//（解析class）
		//测试：beanClass:字节码对象class com.dodi.spring.pojo.User
		//resolveBeanClass方法具体不清楚
		Class<?> beanClass = resolveBeanClass(mbd, beanName);

		//Modifier.isPublic与mbd.isNonPublicAccessAllowed()方法具体不清楚
		//猜：从异常信息看出是判断当前bean是否为public修饰
		if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
		}

		//（如果工厂方法不为空则使用工厂方法初始化策略）
		//（1）
		if (mbd.getFactoryMethodName() != null)  {
			//instantiateUsingFactoryMethod方法后面有详细介绍
			return instantiateUsingFactoryMethod(beanName, mbd, args);
		}

		// Shortcut when re-creating the same bean...
		boolean resolved = false;
		boolean autowireNecessary = false;
		if (args == null) {
			//锁对象为RootBeanDefinition的常量constructorArgumentLock，前面用过
			synchronized (mbd.constructorArgumentLock) {
				//（一个类有多个构造函数，每个构造函数都有不同的参数，
				//所以调用前需要先根据参数锁定构造函数或对应的工厂方法）
				//测试：当前bean中有有参构造方法时，mbd.resolvedConstructorOrFactoryMethod也为null
				//（2）
				if (mbd.resolvedConstructorOrFactoryMethod != null) {
					resolved = true;
					autowireNecessary = mbd.constructorArgumentsResolved;
				}
			}
		}
		//（如果已经解析过则使用解析好的构造函数方法不需要再次锁定）
		//测试：当前bean中有有参构造方法时，resolved也为false
		if (resolved) {
			if (autowireNecessary) {
				//（构造函数自动注入）
				//autowireConstructor方法后面有详细介绍
				return autowireConstructor(beanName, mbd, null, null);
			}
			else {
				//（使用默认构造函数构造）
				//instantiateBean方法后面有详细介绍
				return instantiateBean(beanName, mbd);
			}
		}

		// Need to determine the constructor...
		//（需要根据参数解析构造函数）
		//determineConstructorsFromBeanPostProcessors方法不清楚
		Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
		//if判断中的方法具体不清楚
		//测试：当前bean中有有参构造方法时，ctors为空，mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR
		//为false，mbd.hasConstructorArgumentValues()为true（有有参构造时为true），!ObjectUtils.isEmpty(args)为false
		if (ctors != null ||
				mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
				mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
			//（构造函数自动注入）
			//autowireConstructor方法后面有详细介绍，跟上面方法一样
			return autowireConstructor(beanName, mbd, ctors, args);
		}

		// No special handling: simply use no-arg constructor.
		//（使用默认构造函数构造）
		//instantiateBean方法后面有详细介绍，跟上面方法一样
		return instantiateBean(beanName, mbd);
	}

构造函数自动注入 autowireConstructor
类ConstructorResolver：
	public BeanWrapper autowireConstructor(final String beanName, final RootBeanDefinition mbd,
			Constructor<?>[] chosenCtors, final Object[] explicitArgs) {

		BeanWrapperImpl bw = new BeanWrapperImpl();
		//this.beanFactory.initBeanWrapper不清楚
		//猜初始化BeanWrapperImpl
		this.beanFactory.initBeanWrapper(bw);

		Constructor<?> constructorToUse = null;
		ArgumentsHolder argsHolderToUse = null;
		Object[] argsToUse = null;

		//（expliciArgs通过getBean方法传入）
		//（如果getBean方法调用的时候指定方法参数那么直接使用）
		//{1}
		if (explicitArgs != null) {
			argsToUse = explicitArgs;
		}
		else {
			//（如果在getBean方法时候没有指定则尝试从配置文件中解析）
			Object[] argsToResolve = null;
			//（尝试从缓存中获取）
			//所对象为RootBeanDefinition定义的常量对象constructorArgumentLock
			synchronized (mbd.constructorArgumentLock) {
				//mbd.resolvedConstructorOrFactoryMethod为RootBeanDefinition定义的一个对象。
				//这句代码不清楚
				constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
				//猜：判断缓存中是否有，
				//这判断具体不清楚
				//测试：没进这判断
				if (constructorToUse != null && mbd.constructorArgumentsResolved) {
					// Found a cached constructor...
					//（从缓存中取）
					//mbd.resolvedConstructorArguments为Object数组
					argsToUse = mbd.resolvedConstructorArguments;
					if (argsToUse == null) {
						//（配置的构造函数参数）
						argsToResolve = mbd.preparedConstructorArguments;
					}
				}
			}
			//（如果缓存中存在）
			if (argsToResolve != null) {
				//（解析参数类型，如给定方法的构造函数 A(int,int)则通过此方法后
				//就会把配置中的("1","1")转换为(1,1)）
				//（缓存中的值可能是原始值也可能是最终值）
				//resolvePreparedArguments方法不清楚
				//{2}
				argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve);
			}
		}
		//（没有被缓存）
		if (constructorToUse == null) {
			// Need to resolve the constructor.
			//测试：chosenCtors：null  mbd.getResolvedAutowireMode()：0 
			//RootBeanDefinition.AUTOWIRE_CONSTRUCTOR：3 autowiring：false
			boolean autowiring = (chosenCtors != null ||
					mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
			ConstructorArgumentValues resolvedValues = null;
			//以下代码不清楚
			//猜：获得构造函数参数个数
			int minNrOfArgs;
			if (explicitArgs != null) {
				minNrOfArgs = explicitArgs.length;
			}
			else {
				//（提取配置文件中的配置的构造参数）
				//getConstructorArgumentValues方法不清楚
				//测试：cargs：封装着从配置文件中获得的参数名及值
				ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
				//（用于承载解析后的构造函数参数的值）
				resolvedValues = new ConstructorArgumentValues();
				//（能解析到的参数个数）
				//猜：获得参数个数方法
				//resolveConstructorArguments方法具体不清楚
				//（1）{3}
				minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
			}

			// Take specified constructors, if any.
			//chosenCtors为传进来的参数，Constructor数组
			Constructor<?>[] candidates = chosenCtors;
			if (candidates == null) {
				//从mbd中获得当前bean的字节码对象，前面用过
				//测试：beanClass：class com.dodi.spring.construtorParms.ConUser
				Class<?> beanClass = mbd.getBeanClass();
				try {
					//猜：从字节码对象获得的构造函数数组
					//测试：bd.isNonPublicAccessAllowed()为true
					//beanClass.getDeclaredConstructors()：[public com.dodi.spring.construtorParms.ConUser(java.lang.String,java.lang.String,java.lang.String)]
					//beanClass.getConstructors():[public com.dodi.spring.construtorParms.ConUser(java.lang.String,java.lang.String,java.lang.String)]
					//mbd.isNonPublicAccessAllowed()方法不清楚。
					//（2）
					candidates = (mbd.isNonPublicAccessAllowed() ?
							beanClass.getDeclaredConstructors() : beanClass.getConstructors());
				}
				catch (Throwable ex) {
					throw new BeanCreationException(mbd.getResourceDescription(), beanName,
							"Resolution of declared constructors on bean Class [" + beanClass.getName() +
									"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
				}
			}
			//（排序给定的构造函数，public构造函数优先参数数量降序、非public构造函数参数数量降序）
			//sortConstructors方法不清楚
			AutowireUtils.sortConstructors(candidates);
			int minTypeDiffWeight = Integer.MAX_VALUE;
			Set<Constructor<?>> ambiguousConstructors = null;
			LinkedList<UnsatisfiedDependencyException> causes = null;

			for (int i = 0; i < candidates.length; i++) {
				Constructor<?> candidate = candidates[i];
				//获得当前构造函数的参数类型字节码对象数组，基本类型还是基本类型
				//测试：paramTypes：[int, class java.lang.String, class java.lang.String]
				//（3）
				Class<?>[] paramTypes = candidate.getParameterTypes();

				if (constructorToUse != null && argsToUse.length > paramTypes.length) {
					// Already found greedy constructor that can be satisfied ->
					// do not look any further, there are only less greedy constructors left.
					//（如果已经找到选用的构造函数或者需要的参数个数小于当前的构造函数
					//参数个数到终止，因为已经按照参数个数降序排列）
					break;
				}
				if (paramTypes.length < minNrOfArgs) {
					//（参数个数不相等）
					continue;
				}

				ArgumentsHolder argsHolder;
				if (resolvedValues != null) {
					//（有参数则根据值构造对应参数类型的参数）
					try {
						//（注释上获得参数名称）
						//evaluate方法不清楚
						String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length);
						if (paramNames == null) {
							//（获取参数名称探索器）
							//this.beanFactory.getParameterNameDiscoverer()方法不清楚
							ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
							if (pnd != null) {		
								//（获取指定构造函数的参数名称）
								//猜：获得构造函数的所有参数名字
								//getParameterNames方法具体不清楚
								//测试:paramNames：[uid, name, city](String数组)
								paramNames = pnd.getParameterNames(candidate);
							}
						}
						//（根据名称和数据类型创建参数持有者）
						//createArgumentArray方法不清楚
						argsHolder = createArgumentArray(
								beanName, mbd, resolvedValues, bw, paramTypes, paramNames, candidate, autowiring);
					}
					catch (UnsatisfiedDependencyException ex) {
						if (this.beanFactory.logger.isTraceEnabled()) {
							this.beanFactory.logger.trace(
									"Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex);
						}
						// Swallow and try next constructor.
						if (causes == null) {
							causes = new LinkedList<UnsatisfiedDependencyException>();
						}
						causes.add(ex);
						continue;
					}
				}
				else {
					// Explicit arguments given -> arguments length must match exactly.
					//explicitArgs为getBean传入的参数数组
					if (paramTypes.length != explicitArgs.length) {
						continue;
					}
					//（构造函数没有参数情况）
					argsHolder = new ArgumentsHolder(explicitArgs);
				}
				//（探测是否有不确定性的构造函数存在，例如不同构造函数的参数为父子关系）
				//测试：mbd.isLenientConstructorResolution()：true
				//argsHolder.getAssignabilityWeight(paramTypes)：2147483135
				//argsHolder.getTypeDifferenceWeight(paramTypes)：0
				//typeDiffWeight：0
				//（4）
				int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
						argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
				// Choose this constructor if it represents the closest match.
				//（如果它代表着当前最接近的匹配则选择作为构造函数）
				//以下判断不清楚
				//测试：typeDiffWeight 为0，minTypeDiffWeight为2147483647
				if (typeDiffWeight < minTypeDiffWeight) {
					constructorToUse = candidate;
					argsHolderToUse = argsHolder;
					argsToUse = argsHolder.arguments;
					minTypeDiffWeight = typeDiffWeight;
					ambiguousConstructors = null;
				}
				//以下判断不清楚
				else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
					if (ambiguousConstructors == null) {
						ambiguousConstructors = new LinkedHashSet<Constructor<?>>();
						ambiguousConstructors.add(constructorToUse);
					}
					ambiguousConstructors.add(candidate);
				}
			}
			//constructorToUse，ambiguousConstructors，mbd.isLenientConstructorResolution()
			//参数不清楚
			if (constructorToUse == null) {
				if (causes != null) {
					UnsatisfiedDependencyException ex = causes.removeLast();
					for (Exception cause : causes) {
						this.beanFactory.onSuppressedException(cause);
					}
					throw ex;
				}
				throw new BeanCreationException(mbd.getResourceDescription(), beanName,
						"Could not resolve matching constructor " +
						"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)");
			}
			else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {
				throw new BeanCreationException(mbd.getResourceDescription(), beanName,
						"Ambiguous constructor matches found in bean '" + beanName + "' " +
						"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
						ambiguousConstructors);
			}

			if (explicitArgs == null) {
				//（将解析的构造函数加入缓存）
				//storeCache方法具体不清楚
				argsHolderToUse.storeCache(mbd, constructorToUse);
			}
		}

		try {
			Object beanInstance;
			//安全管理判断，记得前面有用过
			if (System.getSecurityManager() != null) {
				final Constructor<?> ctorToUse = constructorToUse;
				final Object[] argumentsToUse = argsToUse;
				beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
					@Override
					public Object run() {
						//beanFactory.getInstantiationStrategy().instantiate方法不清楚
						return beanFactory.getInstantiationStrategy().instantiate(
								mbd, beanName, beanFactory, ctorToUse, argumentsToUse);
					}
				}, beanFactory.getAccessControlContext());
			}
			else {
				//beanFactory.getInstantiationStrategy().instantiate方法不清楚，上面用过
				//（5）
				beanInstance = this.beanFactory.getInstantiationStrategy().instantiate(
						mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
			}
			//（将构建的实例加入BeanWrapper中）
			bw.setWrappedInstance(beanInstance);
			return bw;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"Bean instantiation via constructor failed", ex);
		}
	}

类AbstractAutowireCapableBeanFactory：	
不带参的实例化  instantiateBean
	//与前面有参实例化一样
	protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
		try {
			Object beanInstance;
			final BeanFactory parent = this;
			if (System.getSecurityManager() != null) {
				beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
					@Override
					public Object run() {
						return getInstantiationStrategy().instantiate(mbd, beanName, parent);
					}
				}, getAccessControlContext());
			}
			else {
				beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
			}
			BeanWrapper bw = new BeanWrapperImpl(beanInstance);
			initBeanWrapper(bw);
			return bw;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
		}
	}
类SimpleInstantiationStrategy：	
	public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) {
		// Don't override the class with CGLIB if no overrides.
		//（如果有需要覆盖或者动态替换的方法则当然需要使用cglib进行动态代理，
		//因为可以在创建代理的同时将动态方法织入类中）
		//（但是如果没有需要动态改变的方法，为了方便直接反射就可以了）
		if (bd.getMethodOverrides().isEmpty()) {
			//没有覆盖的方法，不需动态代理
			Constructor<?> constructorToUse;
			//锁对象为RootBeanDefinition中的常量对象postProcessingLock，前面用过
			synchronized (bd.constructorArgumentLock) {
				//resolvedConstructorOrFactoryMethod方法不清楚
				constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
				if (constructorToUse == null) {
					//从RootBeanDefinition中获得当前bean的字节码对象
					//测试：clazz：class com.dodi.spring.pojo.User
					final Class<?> clazz = bd.getBeanClass();
					if (clazz.isInterface()) {
						throw new BeanInstantiationException(clazz, "Specified class is an interface");
					}
					try {
						//安全管理判断，记得前面有用过
						if (System.getSecurityManager() != null) {
							constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor<?>>() {
								@Override
								public Constructor<?> run() throws Exception {
									return clazz.getDeclaredConstructor((Class[]) null);
								}
							});
						}
						else {
							//使用反射获得（当前bean）构造方法
							//测试：constructorToUse：public com.dodi.spring.pojo.User()
							constructorToUse =	clazz.getDeclaredConstructor((Class[]) null);
						}
						//resolvedConstructorOrFactoryMethod为Object,不清楚
						bd.resolvedConstructorOrFactoryMethod = constructorToUse;
					}
					catch (Exception ex) {
						throw new BeanInstantiationException(clazz, "No default constructor found", ex);
					}
				}
			}
			//猜：调用对象工具类初始化bean(使用反射newInstance方法)
			//instantiateClass具体不清楚
			return BeanUtils.instantiateClass(constructorToUse);
		}
		else {
			// Must generate CGLIB subclass.
			//动态代理实现动态方法织入
			//instantiateWithMethodInjection方法后面有详细介绍
			return instantiateWithMethodInjection(bd, beanName, owner);
		}
	}

//动态代理技术，后面第七章AOP有详细介绍	
类CglibSubclassingInstantiationStrategy：	
		protected Object instantiateWithMethodInjection(RootBeanDefinition bd, String beanName, BeanFactory owner,
			Constructor<?> ctor, Object... args) {

		// Must generate CGLIB subclass...
		return new CglibSubclassCreator(bd, owner).instantiate(ctor, args);
	}

类CglibSubclassingInstantiationStrategy：	
		public Object instantiate(Constructor<?> ctor, Object... args) {
			Class<?> subclass = createEnhancedSubclass(this.beanDefinition);
			Object instance;
			if (ctor == null) {
				instance = BeanUtils.instantiate(subclass);
			}
			else {
				try {
					Constructor<?> enhancedSubclassConstructor = subclass.getConstructor(ctor.getParameterTypes());
					instance = enhancedSubclassConstructor.newInstance(args);
				}
				catch (Exception ex) {
					throw new BeanInstantiationException(this.beanDefinition.getBeanClass(),
							"Failed to invoke constructor for CGLIB enhanced subclass [" + subclass.getName() + "]", ex);
				}
			}
			// SPR-10785: set callbacks directly on the instance instead of in the
			// enhanced class (via the Enhancer) in order to avoid memory leaks.
			Factory factory = (Factory) instance;
			factory.setCallbacks(new Callback[] {NoOp.INSTANCE,
					new LookupOverrideMethodInterceptor(this.beanDefinition, this.owner),
					new ReplaceOverrideMethodInterceptor(this.beanDefinition, this.owner)});
			return instance;
		}	
//动态代理技术，后面第七章AOP有详细介绍	

5.7.2 记录创建bean的ObjectFactory

类AbstractAutowireCapableBeanFactory的doCreateBean函数中（在pdf中有详细介绍）：

		// Eagerly cache singletons to be able to resolve circular references
		// even when triggered by lifecycle interfaces like BeanFactoryAware.
		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
				isSingletonCurrentlyInCreation(beanName));
		if (earlySingletonExposure) {
			if (logger.isDebugEnabled()) {
				logger.debug("Eagerly caching bean '" + beanName +
						"' to allow for resolving potential circular references");
			}
			//（为避免后期循环依赖，可以在bean初始化完成前将创建实例的ObjectFactory加入工厂）
			addSingletonFactory(beanName, new ObjectFactory<Object>() {
				@Override
				public Object getObject() throws BeansException {
					//（对bean再一次依赖引用，主要应用smartInstantiationAware BeanPostProcessor，）
					//（其中我们熟知的AOP就是在这里将advice动态织入bean中，若没有则直接返回bean，不作任何处理）
					//（getEarlyBeanReference方法后面有详细介绍）
					return getEarlyBeanReference(beanName, mbd, bean);
				}
			});
		}

类AbstractAutowireCapableBeanFactory：
	//循环依赖后面仔细看看
	protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
		Object exposedObject = bean;
		if (bean != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
					SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
					exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
					if (exposedObject == null) {
						return exposedObject;
					}
				}
			}
		}
		return exposedObject;
	}

5.7.3 属性注入
类AbstractAutowireCapableBeanFactory：
	protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
		//猜：获得当前bean所需注入的所有属性
		//测试：pvs:PropertyValues: length=2; bean property 'user'; bean property 'cid'
		//getPropertyValues具体不清楚
		PropertyValues pvs = mbd.getPropertyValues();

		if (bw == null) {
			//（isEmpty很多地方用到，有时间仔细看看）
			if (!pvs.isEmpty()) {
				throw new BeanCreationException(
						mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
			}
			else {
				// Skip property population phase for null instance.
				//（没有可填充的属性）
				return;
			}
		}

		// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
		// state of the bean before properties are set. This can be used, for example,
		// to support styles of field injection.
		//（给InstantiationAwareBeanPostProcessors最后一次机会在属性设置前来改变bean）
		//（如：可以用来支持属性注入的类型）
		boolean continueWithPropertyPopulation = true;
		
		//ooo以下的判断不理解，测试时没进去，后面再仔细看
		//测试：mbd.isSynthetic():false hasInstantiationAwareBeanPostProcessors():false
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					//（返回值为是否继续填充bean）
					//（1）
					if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
						continueWithPropertyPopulation = false;
						break;
					}
				}
			}
		}
		//（如果后处理器发出停止填充命令则终止后续的执行）
		if (!continueWithPropertyPopulation) {
			return;
		}
		
		//测试：mbd.getResolvedAutowireMode():0 
		//RootBeanDefinition.AUTOWIRE_BY_NAME:1
		//RootBeanDefinition.AUTOWIRE_BY_TYPE：2
		//猜：此判断为注解注入方式
		//测试：mbd.getResolvedAutowireMode()：1
		//RootBeanDefinition.AUTOWIRE_BY_NAME:1
		//（2）
		if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
				mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
			//猜：重新创建一个一模一样的MutablePropertyValues,在后面使用
			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

			// Add property values based on autowire by name if applicable.
			//（根据名称自动注入）
			if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
				//autowireByName方法后面有详细介绍
				autowireByName(beanName, mbd, bw, newPvs);
			}

			// Add property values based on autowire by type if applicable.
			//（根据类型自动注入）
			if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
				//autowireByType方法后面有详细介绍
				autowireByType(beanName, mbd, bw, newPvs);
			}

			pvs = newPvs;
		}
		//（后处理器已经初始化）
		boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
		//（需要依赖检查）
		boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
		//以下判断为需要依赖检查才执行，后面再仔细看
		if (hasInstAwareBpps || needsDepCheck) {
			PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
			if (hasInstAwareBpps) {
				for (BeanPostProcessor bp : getBeanPostProcessors()) {
					if (bp instanceof InstantiationAwareBeanPostProcessor) {
						InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
						//（对所有需要依赖检查的属性进行后处理）
						//（3）
						pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
						if (pvs == null) {
							return;
						}
					}
				}
			}
			if (needsDepCheck) {
				//（依赖检查，对应depends-on属性，3.0已经弃用此属性）
				checkDependencies(beanName, mbd, filteredPds, pvs);
			}
		}

		//（将属性应用到bean中）
		//applyPropertyValues方法后面有详细介绍
		//（4）
		applyPropertyValues(beanName, mbd, bw, pvs);
	}

1.根据名字自动注入
类AbstractAutowireCapableBeanFactory：
	protected void autowireByName(
			String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
		//（寻找bw中需要依赖注入的属性）
		//猜：要根据名字注入属性的字符串数组
		//测试：propertyNames：[phone, student]
		//unsatisfiedNonSimpleProperties方法具体不清楚
		String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
		for (String propertyName : propertyNames) {
			//containsBean方法具体不清楚
			//猜：containsBean方法是判断spring容器中是否有propertyName的bean
			if (containsBean(propertyName)) {
				
				//（递归初始化相关bean）
				Object bean = getBean(propertyName);
				//猜：加入到pvs中
				pvs.add(propertyName, bean);
				//（注册依赖）
				//registerDependentBean具体不清楚
				registerDependentBean(propertyName, beanName);
				if (logger.isDebugEnabled()) {
					logger.debug("Added autowiring by name from bean name '" + beanName +
							"' via property '" + propertyName + "' to bean named '" + propertyName + "'");
				}
			}
			else {
				if (logger.isTraceEnabled()) {
					logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
							"' by name: no matching bean found");
				}
			}
		}
	}	

	protected void autowireByType(
			String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
		//尝试从父类中获得TypeConverter
		TypeConverter converter = getCustomTypeConverter();
		if (converter == null) {
			converter = bw;
		}

		Set<String> autowiredBeanNames = new LinkedHashSet<String>(4);
		//（寻找bw中需要依赖注入的属性）
		//上面用过此方法
		//测试：propertyNames：[phone, student]
		String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
		for (String propertyName : propertyNames) {
			try {
				//测试：pd：org.springframework.beans.GenericTypeAwarePropertyDescriptor[name=phone]
				//getPropertyDescriptor方法不清楚
				PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
				// Don't try autowiring by type for type Object: never makes sense,
				// even if it technically is a unsatisfied, non-simple property.
				//测试：Object.class：class java.lang.Object
				//pd.getPropertyType()：class com.dodi.spring.propertyInject.Phone
				if (Object.class != pd.getPropertyType()) {
					//（探测指定属性的set方法）
					//测试：methodParam：封装着与propertyName字节码对象与set方法相关的MethodParameter类
					//getWriteMethodParameter方法具体不清楚
					MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
					// Do not allow eager init for type matching in case of a prioritized post-processor.
					//测试：eager：true
					//bw.getWrappedClass()：class com.dodi.spring.propertyInject.Person
					//反射方法：isAssignableFrom方法调用方法的字节码对象为参数字节码对象的父类时（或相同类型）返回true，
					//否则返回false
					boolean eager = !PriorityOrdered.class.isAssignableFrom(bw.getWrappedClass());
					DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
					//（解析指定beanName的属性所匹配的值，并把解析到的属性名称
					//存储在autowiredBeanNames中，当属性存在多个封装bean时如：）
					//（@Autowired private List<A> aList;将会找到所有匹配A类型的bean并将其注入）
					//resolveDependency方法不清楚，不理解
					//测试：autowiredArgument：Phone [brand=hw, price=3000]
					//resolveDependency方法后面有详细介绍
					Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
					//不为空，加入到pvs中
					if (autowiredArgument != null) {
						pvs.add(propertyName, autowiredArgument);
					}
					for (String autowiredBeanName : autowiredBeanNames) {
						//（注册依赖）
						//上面用过
						registerDependentBean(autowiredBeanName, beanName);
						if (logger.isDebugEnabled()) {
							logger.debug("Autowiring by type from bean name '" + beanName + "' via property '" +
									propertyName + "' to bean named '" + autowiredBeanName + "'");
						}
					}
					//清除autowiredBeanNames，防止下次重复
					autowiredBeanNames.clear();
				}
			}
			catch (BeansException ex) {
				throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
			}
		}
	}
	
	类DefaultListableBeanFactory:
		public Object resolveDependency(DependencyDescriptor descriptor, String beanName,
			Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException {

		//initParameterNameDiscovery方法不清楚，
		//传入参数方法getParameterNameDiscoverer不清楚
		//测试：getParameterNameDiscoverer()：org.springframework.core.DefaultParameterNameDiscoverer@48974e45看不出封装什么
		descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
	
		//测试：descriptor.getDependencyType()：interface java.util.List
		//javaUtilOptionalClass：class java.util.Optional
		//猜：class java.util.Optional的特殊处理
		if (descriptor.getDependencyType().equals(javaUtilOptionalClass)) {
			//做了什么特殊处理不清楚
			return new OptionalDependencyFactory().createOptionalDependency(descriptor, beanName);
		}
		else if (ObjectFactory.class == descriptor.getDependencyType()) {			
			//（ObjectFactory类注入的特殊处理）
			//做了什么特殊处理不清楚
			return new DependencyObjectFactory(descriptor, beanName);
		}
		else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
			//（javaxInjectProviderClass类的特殊处理）
			//做了什么特殊处理不清楚
			return new DependencyProviderFactory().createDependencyProvider(descriptor, beanName);
		}
		else {
			//以下代码处理不清楚
			//猜：缓存result
			Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(descriptor, beanName);
			if (result == null) {
				//（通用处理逻辑）
				//doResolveDependency方法后面有详细介绍
				result = doResolveDependency(descriptor, beanName, autowiredBeanNames, typeConverter);
			}
			return result;
		}
		
类DefaultListableBeanFactory：
//测试时用了List集合		
	public Object doResolveDependency(DependencyDescriptor descriptor, String beanName,
			Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException {

		//测试：type：interface java.util.List
		//猜：从descriptor中获得依赖注入类型
		//getDependencyType方法具体不清楚
		Class<?> type = descriptor.getDependencyType();
		//（用于支持Spring中新增的注解@Value）
		//以下代码具体不清楚
		Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
		if (value != null) {
			//通过@Value注入的为String类型，需要做特殊处理，以后再看
			if (value instanceof String) {
				String strVal = resolveEmbeddedValue((String) value);
				BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null);
				value = evaluateBeanDefinitionString(strVal, bd);
			}
			TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
			return (descriptor.getField() != null ?
					converter.convertIfNecessary(value, type, descriptor.getField()) :
					converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
		}
		//（如果解析器没有成功解析，则需要考虑各种情况）
		//（属性是数组类型）
		if (type.isArray()) {
			Class<?> componentType = type.getComponentType();
			DependencyDescriptor targetDesc = new DependencyDescriptor(descriptor);
			targetDesc.increaseNestingLevel();
			//（根据属性类型找到beanFactory中所有类型的匹配bean）
			//（返回值的构成为：key=匹配的beanName,value=beanName对应的实例化后的bean（通过getBean(beanName)返回））
			Map<String, Object> matchingBeans = findAutowireCandidates(beanName, componentType, targetDesc);
			if (matchingBeans.isEmpty()) {
				//（如果autowire的require属性为true而找到的匹配项却为空则只能抛出异常）
				if (descriptor.isRequired()) {
					raiseNoSuchBeanDefinitionException(componentType, "array of " + componentType.getName(), descriptor);
				}
				return null;
			}
			if (autowiredBeanNames != null) {
				autowiredBeanNames.addAll(matchingBeans.keySet());
			}
			TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
			//（通过转换器将bean的值转换为对应的type类型）
			Object result = converter.convertIfNecessary(matchingBeans.values(), type);
			if (getDependencyComparator() != null && result instanceof Object[]) {
				Arrays.sort((Object[]) result, adaptDependencyComparator(matchingBeans));
			}
			return result;
		}
		//（属性是Collection类型）
		//isAssignableFrom为jdk提供方法，判断参数的类型是否为子类或者子接口
		else if (Collection.class.isAssignableFrom(type) && type.isInterface()) {
			//测试：elementType：class com.dodi.spring.propertyInject.User
			//猜：获得集合中的泛型中类型
			//获得泛型类型方法getCollectionType具体不清楚
			Class<?> elementType = descriptor.getCollectionType();
			if (elementType == null) {
				if (descriptor.isRequired()) {
					throw new FatalBeanException("No element type declared for collection [" + type.getName() + "]");
				}
				return null;
			}
			//猜：重新复制一个descriptor对象，供下面使用
			DependencyDescriptor targetDesc = new DependencyDescriptor(descriptor);
			//使nestingLevel加一，这样做不清楚
			targetDesc.increaseNestingLevel();
			//测试：matchingBeans：{user1=com.dodi.spring.propertyInject.User@3b6d844d, user2=com.dodi.spring.propertyInject.User@36804139}
			//猜：findAutowireCandidates方法从targetDesc获得要注入的对象并封装为Map
			//findAutowireCandidates方法具体不清楚
			Map<String, Object> matchingBeans = findAutowireCandidates(beanName, elementType, targetDesc);
			if (matchingBeans.isEmpty()) {
				if (descriptor.isRequired()) {
					raiseNoSuchBeanDefinitionException(elementType, "collection of " + elementType.getName(), descriptor);
				}
				return null;
			}
			if (autowiredBeanNames != null) {
				//测试：matchingBeans.keySet():[user1, user2]
				//把需要注入到集合的bean的id保存到Set集合autowiredBeanNames中
				autowiredBeanNames.addAll(matchingBeans.keySet());
			}
			//typeConverter为传入的参数
			TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
			//测试：matchingBeans.values()：[com.dodi.spring.propertyInject.User@3b6d844d, com.dodi.spring.propertyInject.User@36804139]
			//result:ArrayList集合[com.dodi.spring.propertyInject.User@3b6d844d, com.dodi.spring.propertyInject.User@36804139]
			//convertIfNecessary方法不清楚
			Object result = converter.convertIfNecessary(matchingBeans.values(), type);
			//猜：以下判断如果为list则进行排序
			//以下判断不清楚什么作用
			//测试：modCount发生了改变
			if (getDependencyComparator() != null && result instanceof List) {
				//adaptDependencyComparator方法不清楚
				Collections.sort((List<?>) result, adaptDependencyComparator(matchingBeans));
			}
			return result;
		}
		//（属性是Map类型）
		else if (Map.class.isAssignableFrom(type) && type.isInterface()) {
			Class<?> keyType = descriptor.getMapKeyType();
			if (String.class != keyType) {
				if (descriptor.isRequired()) {
					throw new FatalBeanException("Key type [" + keyType + "] of map [" + type.getName() +
							"] must be [java.lang.String]");
				}
				return null;
			}
			Class<?> valueType = descriptor.getMapValueType();
			if (valueType == null) {
				if (descriptor.isRequired()) {
					throw new FatalBeanException("No value type declared for map [" + type.getName() + "]");
				}
				return null;
			}
			DependencyDescriptor targetDesc = new DependencyDescriptor(descriptor);
			targetDesc.increaseNestingLevel();
			Map<String, Object> matchingBeans = findAutowireCandidates(beanName, valueType, targetDesc);
			if (matchingBeans.isEmpty()) {
				if (descriptor.isRequired()) {
					raiseNoSuchBeanDefinitionException(valueType, "map with value type " + valueType.getName(), descriptor);
				}
				return null;
			}
			if (autowiredBeanNames != null) {
				autowiredBeanNames.addAll(matchingBeans.keySet());
			}
			return matchingBeans;
		}
		else {
			Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
			if (matchingBeans.isEmpty()) {
				if (descriptor.isRequired()) {
					raiseNoSuchBeanDefinitionException(type, "", descriptor);
				}
				return null;
			}
			if (matchingBeans.size() > 1) {
				String primaryBeanName = determineAutowireCandidate(matchingBeans, descriptor);
				if (primaryBeanName == null) {
					throw new NoUniqueBeanDefinitionException(type, matchingBeans.keySet());
				}
				if (autowiredBeanNames != null) {
					autowiredBeanNames.add(primaryBeanName);
				}
				return matchingBeans.get(primaryBeanName);
			}
			// We have exactly one match.
			//（已经可以确定只有一个匹配项）
			Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
			if (autowiredBeanNames != null) {
				autowiredBeanNames.add(entry.getKey());
			}
			return entry.getValue();
		}
	}
	}
	
类AbstractAutowireCapableBeanFactory：	
	protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
		//猜：判断是否有属性注入，没有直接返回
		if (pvs == null || pvs.isEmpty()) {
			return;
		}

		MutablePropertyValues mpvs = null;
		List<PropertyValue> original;

		//安全管理判断，记得前面有用过
		if (System.getSecurityManager() != null) {
			if (bw instanceof BeanWrapperImpl) {
				((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
			}
		}
		//测试：pvs instanceof MutablePropertyValues为true
		//猜：MutablePropertyValues类为封装着属性集合的类
		if (pvs instanceof MutablePropertyValues) {
			mpvs = (MutablePropertyValues) pvs;
			//（如果mpvs中的值已经被转换为对应的类型那么可以直接设置到beanwapper中）
			//是否被修改
			if (mpvs.isConverted()) {
				// Shortcut: use the pre-converted values as-is.
				try {
					bw.setPropertyValues(mpvs);
					return;
				}
				catch (BeansException ex) {
					throw new BeanCreationException(
							mbd.getResourceDescription(), beanName, "Error setting property values", ex);
				}
			}
			//测试：original：[bean property 'user', bean property 'cid']的ArrayList集合
			original = mpvs.getPropertyValueList();
		}
		else {
			//（如果pvs并不是使用MutablePropertyValues封装的类型，那么直接使用原始的属性获取方法）
			original = Arrays.asList(pvs.getPropertyValues());
		}

		//测试：converter:null
		//getCustomTypeConverter不清楚
		TypeConverter converter = getCustomTypeConverter();
		if (converter == null) {
			converter = bw;
		}
		//（获取对应的解析器）
		//BeanDefinitionValueResolver类不清楚
		BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);

		// Create a deep copy, resolving any references for values.
		//猜：创建一个放注入属性的ArrayList集合
		List<PropertyValue> deepCopy = new ArrayList<PropertyValue>(original.size());		
		boolean resolveNecessary = false;
		//（遍历属性，将属性转换为对应类的对应属性的类型）
		for (PropertyValue pv : original) {
			if (pv.isConverted()) {
				deepCopy.add(pv);
			}
			else {
				//测试：propertyName：user
				//originalValue：<user>
				//resolvedValue：com.dodi.spring.propertyInject.User@71d44a3
				//convertedValue：com.dodi.spring.propertyInject.User@71d44a3
				String propertyName = pv.getName();
				Object originalValue = pv.getValue();
				//resolveValueIfNecessary后面有详细介绍
				Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
				Object convertedValue = resolvedValue;
				//测试：bw.isWritableProperty(propertyName)：true
				//PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName)：false
				//isWritableProperty方法与isNestedOrIndexedProperty方法不清楚
				boolean convertible = bw.isWritableProperty(propertyName) &&
						!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
				if (convertible) {
					//测试：convertedValue：com.dodi.spring.propertyInject.User@71d44a3
					//convertForProperty方法不清楚
					convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
				}
				// Possibly store converted value in merged bean definition,
				// in order to avoid re-conversion for every created bean instance.
				//测试：resolvedValue == originalValue：false
				//以下判断不清楚
				if (resolvedValue == originalValue) {
					//测试时没进入，以后再看
					if (convertible) {
						pv.setConvertedValue(convertedValue);
					}
					deepCopy.add(pv);
				}
				else if (convertible && originalValue instanceof TypedStringValue &&
						!((TypedStringValue) originalValue).isDynamic() &&
						!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
					//测试：当注入属性为基本类型时进入这里
					pv.setConvertedValue(convertedValue);
					deepCopy.add(pv);
				}
				else {
					//测试：当注入属性为引用类型时进入这里
					resolveNecessary = true;
					//添加到deepCopy属性的ArrayList集合中
					deepCopy.add(new PropertyValue(pv, convertedValue));
				}
			}
		}
		//以下判断不清楚
		if (mpvs != null && !resolveNecessary) {
			mpvs.setConverted();
		}

		// Set our (possibly massaged) deep copy.
		try {
			//setPropertyValues方法把List中的属性注入到bean中，(最终其实通过反射获得set方法注入)
			bw.setPropertyValues(new MutablePropertyValues(deepCopy));
		}
		catch (BeansException ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Error setting property values", ex);
		}
	}
类AbstractAutowireCapableBeanFactory：	
	protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged(new PrivilegedAction<Object>() {
				@Override
				public Object run() {
					//（invokeAwareMethods后面有详细介绍）
					invokeAwareMethods(beanName, bean);
					return null;
				}
			}, getAccessControlContext());
		}
		else {
			//（对特殊的bean处理：Aware、BeanClassLoaderAware、BeanFactoryAware）
			//（invokeAwareMethods，跟上面一样，后面有详细介绍）
			invokeAwareMethods(beanName, bean);
		}

		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
			//（应用后处理器）
			//applyBeanPostProcessorsBeforeInitialization方法后面有详细介绍
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
			//（激活用户自定义的init方法）
			////（invokeInitMethods后面有详细介绍）
			invokeInitMethods(beanName, wrappedBean, mbd);
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					(mbd != null ? mbd.getResourceDescription() : null),
					beanName, "Invocation of init method failed", ex);
		}

		if (mbd == null || !mbd.isSynthetic()) {
			//（后处理器的应用）
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}
		return wrappedBean;
	}
	
	1.激活Aware方法
	//测试使用com.dodi.spring.beanFactoryAware包中方法
	private void invokeAwareMethods(final String beanName, final Object bean) {
		if (bean instanceof Aware) {
			if (bean instanceof BeanNameAware) {
				((BeanNameAware) bean).setBeanName(beanName);
			}
			if (bean instanceof BeanClassLoaderAware) {
				((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
			}
			if (bean instanceof BeanFactoryAware) {
				//测试：AbstractAutowireCapableBeanFactory.this：org.springframework.beans.factory.support.DefaultListableBeanFactory@3c130745: defining beans [test,hello]; root of factory hierarchy
				((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
			}
		}
	}
	
	2.处理器的应用（不理解）
类AbstractAutowireCapableBeanFactory：	
	public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
			throws BeansException {
		//测试：existingBean：com.dodi.spring.beanFactoryAware.Test@4d5d943d
		Object result = existingBean;
		//测试：getBeanPostProcessors()：[org.springframework.context.support.ApplicationContextAwareProcessor@4c583ecf, org.springframework.context.support.PostProcessorRegistrationDelegate$BeanPostProcessorChecker@692f203f, org.springframework.context.support.PostProcessorRegistrationDelegate$ApplicationListenerDetector@48f2bd5b]
		for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
			//postProcessBeforeInitialization方法后面有详细介绍
			result = beanProcessor.postProcessBeforeInitialization(result, beanName);
			if (result == null) {
				return result;
			}
		}
		return result;
	}
	
类AbstractAutowireCapableBeanFactory：	
	public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException {

		Object result = existingBean;
		for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
			//postProcessAfterInitialization方法后面有详细介绍
			result = beanProcessor.postProcessAfterInitialization(result, beanName);
			if (result == null) {
				return result;
			}
		}
		return result;
	}

类AbstractAutowireCapableBeanFactory：
//在com.dodi.spring.initMethod包中测试
	protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)
			throws Throwable {

		//（首先会检查是否是InitializingBean，如果是的话需要调用afterPropertiesSet方法）	
		boolean isInitializingBean = (bean instanceof InitializingBean);
		if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
			if (logger.isDebugEnabled()) {
				logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
			}
			if (System.getSecurityManager() != null) {
				try {
					AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
						@Override
						public Object run() throws Exception {
							((InitializingBean) bean).afterPropertiesSet();
							return null;
						}
					}, getAccessControlContext());
				}
				catch (PrivilegedActionException pae) {
					throw pae.getException();
				}
			}
			else {
				//（属性初始化后的处理）
				((InitializingBean) bean).afterPropertiesSet();
			}
		}

		//配置了init-method时会进入这里
		if (mbd != null) {
			String initMethodName = mbd.getInitMethodName();
			if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
					!mbd.isExternallyManagedInitMethod(initMethodName)) {
				//（调用自定义初始化方法）
				invokeCustomInitMethod(beanName, bean, mbd);
			}
		}
	}

5.7.5 注册DisposableBean（销毁bean）
	protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
		AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
		if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
			if (mbd.isSingleton()) {
				// Register a DisposableBean implementation that performs all destruction
				// work for the given bean: DestructionAwareBeanPostProcessors,
				// DisposableBean interface, custom destroy method.
				
				//（单例模式下注册需要销毁的bean，此方法中会处理实现DisposableBean的bean）
				//（并且对所有的bean使用DestructionAwareBeanPostProcessors处理）
				//（DisposableBean DestructionAwarBeanPostProcessors,）
				//registerDisposableBean方法后面有详细介绍
				//就是放到类DefaultListableBeanFactory集合disposableBeans map中，
				registerDisposableBean(beanName,
						new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
			}
			else {
				// A bean with a custom scope...
				//（自定义scope的处理）
				Scope scope = this.scopes.get(mbd.getScope());
				if (scope == null) {
					throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
				}
				//（registerDestructionCallback方法后面有详细介绍）
				scope.registerDestructionCallback(beanName,
						new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
			}
		}
	}	


	
第六章 容器的功能拓展

类ClassPathXmlApplicationContext：	
	public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
		this(new String[] {configLocation}, true, null);
	}

类ClassPathXmlApplicationContext：
	public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
			throws BeansException {

		super(parent);
		//setConfigLocations方法后面有详细介绍
		setConfigLocations(configLocations);
		if (refresh) {
			//refresh方法后面有详细介绍
			refresh();
		}
	}
	
6.1 设置配置路径

类AbstractRefreshableConfigApplicationContext：
	public void setConfigLocations(String... locations) {
		if (locations != null) {
			Assert.noNullElements(locations, "Config locations must not be null");
			this.configLocations = new String[locations.length];
			for (int i = 0; i < locations.length; i++) {
				//（解析给定路径）
				//resolvePath方法后面有详细介绍
				//如果数组中包含特殊符号，如${var},resolvePath方法中会搜寻匹配的系统变量并替换
				//resolvePath方法具体不清楚
				this.configLocations[i] = resolvePath(locations[i]).trim();
			}
		}
		else {
			this.configLocations = null;
		}
	}

6.2 拓展功能

类AbstractApplicationContext：
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.
			//（准备刷新的上下文环境）
			//prepareRefresh方法后面有详细介绍
			//（1）
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			//（初始化BeanFactory，并进行XML文件读取）
			//obtainFreshBeanFactory方法后面有详细介绍
			//（2）
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			//（对BeanFactory进行各种功能填充）
			//prepareBeanFactory方法后面有详细介绍
			//（3）
			prepareBeanFactory(beanFactory);

			try {
				// Allows post-processing of the bean factory in context subclasses.
				//（子类覆盖方法做额外的处理）
				//postProcessBeanFactory方法后面有详细介绍
				//（4）
				postProcessBeanFactory(beanFactory);

				// Invoke factory processors registered as beans in the context.
				//（激活各种BeanFactory处理器）
				//invokeBeanFactoryPostProcessors方法后面有详细介绍
				//（5）
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				//（注册拦截Bean创建的Bean处理器，这里只是注册，真正的调用是在getBean时候）
				//registerBeanPostProcessors方法后面有详细介绍
				//（6）
				registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
				//（为上下文初始化Message源，即不同语言的消息体，国际化处理）
				//initMessageSource方法后面有详细介绍
				//（7）
				initMessageSource();

				// Initialize event multicaster for this context.
				//初始化应用消息广播器，并放入"applicationEventMulticaster"bean中
				//initApplicationEventMulticaster方法后面有详细介绍
				//（8）
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				//（留给子类来初始化其它的Bean）
				//onRefresh方法后面有详细介绍
				//（9）
				onRefresh();

				// Check for listener beans and register them.
				//（在所有注册的bean中查找Listener bean，注册到消息广播器中）
				//registerListeners方法后面有详细介绍
				//（10）
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.
				//（初始化剩下的单实例（非惰性的））
				//finishBeanFactoryInitialization方法后面有详细介绍
				//（11）
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				//（完成刷新过程，通知生命周期处理器lifecycleProcessor刷新过程，同时发出ContextRefreshEvent通知别人）
				//finishRefresh方法后面有详细介绍
				//（12）
				finishRefresh();
			}

			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				// Destroy already created singletons to avoid dangling resources.
				//destroyBeans方法后面有详细介绍
				destroyBeans();

				// Reset 'active' flag.
				//cancelRefresh方法后面有详细介绍
				cancelRefresh(ex);

				// Propagate exception to caller.
				throw ex;
			}

			finally {
				// Reset common introspection caches in Spring's core, since we
				// might not ever need metadata for singleton beans anymore...
				resetCommonCaches();
			}
		}
	}	

6.3 环境准备
类AbstractApplicationContext：
	protected void prepareRefresh() {
		this.startupDate = System.currentTimeMillis();
		this.closed.set(false);
		this.active.set(true);

		if (logger.isInfoEnabled()) {
			logger.info("Refreshing " + this);
		}

		// Initialize any placeholder property sources in the context environment
		//（留给子类覆盖）
		//initPropertySources方法后面有详细介绍
		//initPropertySources方法为空方法
		initPropertySources();

		// Validate that all properties marked as required are resolvable
		// see ConfigurablePropertyResolver#setRequiredProperties
		//（验证需要的属性文件是否都已经放入环境中）
		//getEnvironment().validateRequiredProperties()方法后面有详细介绍
		//validateRequiredProperties方法对属性进行验证，没有对应的环境变量时抛出异常
		getEnvironment().validateRequiredProperties();

		// Allow for the collection of early ApplicationEvents,
		// to be published once the multicaster is available...
		this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>();
	}
	
6.4 加载BeanFactory

类AbstractApplicationContext：
	protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
		//（初始化BeanFactory，并进行XML文件读取，并将得到的BeanFactory记录在当前实体的属性中）
		refreshBeanFactory();
		//（返回当前实体的beanFactory属性）
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		if (logger.isDebugEnabled()) {
			logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
		}
		return beanFactory;
	}

类AbstractRefreshableApplicationContext：
	protected final void refreshBeanFactory() throws BeansException {
		//猜：判断是否有BeanFactory，如有则销毁和关闭
		if (hasBeanFactory()) {
			destroyBeans();
			closeBeanFactory();
		}
		try {
			//（创建DefaultListableBeanFactory）
			//看：有从父Bean中获得beanFactory
			//（1）
			DefaultListableBeanFactory beanFactory = createBeanFactory();
			//（为了序列化指定id，如果需要的话，让这个BeanFactory从id反序列化到BeanFactory对象）
			//（2）
			beanFactory.setSerializationId(getId());
			//（定制beanFactory，设置相关属性，包括是否允许覆盖同名称的不同定义的对象以及循环依赖）
			//（设置@Autowired和@Qualifier注解解析器QualifierAnnotationAutowire CandidateResolver）
			//customizeBeanFactory方法后面有详细介绍
			//（3）
			customizeBeanFactory(beanFactory);
			//（初始化DodumentReader，并进行XML文件读取及解析）
			//loadBeanDefinitions方法后面有详细介绍
			//（4）
			loadBeanDefinitions(beanFactory);
			synchronized (this.beanFactoryMonitor) {
				//（5）
				this.beanFactory = beanFactory;
			}
		}
		catch (IOException ex) {
			throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
		}
	}

6.4.1 定制BeanFactory

类AbstractRefreshableApplicationContext：
	protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
		
		//（如果属性allowBeanDefinitionOverriding不为空，设置给beanFactory对象相应属性）
		//（此属性的含义：是否允许覆盖同名称的不同定义的对象）
		if (this.allowBeanDefinitionOverriding != null) {
			beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
		}
		//（如果属性allowCircularReferences不为空，设置给beanFactory对象相应属性）
		//（此属性的含义：是否允许bean之间存在循环依赖）
		if (this.allowCircularReferences != null) {
			beanFactory.setAllowCircularReferences(this.allowCircularReferences);
		}
	}	

	-------------------------------QualifierAnnotationAutowireCandidateResolver方法没有
	
6.4.2 加载BeanDefinition

类AbstractXmlApplicationContext：
	protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
		// Create a new XmlBeanDefinitionReader for the given BeanFactory.
		//（为指定beanFactory创建XmlBeanfinitionReader）
		XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

		// Configure the bean definition reader with this context's
		// resource loading environment.
		//（对beanDefinitionReader进行环境变量的设置）
		beanDefinitionReader.setEnvironment(this.getEnvironment());
		beanDefinitionReader.setResourceLoader(this);
		beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

		// Allow a subclass to provide custom initialization of the reader,
		// then proceed with actually loading the bean definitions.
		//（对BeanDefinitionReader进行设置，可以覆盖）
		initBeanDefinitionReader(beanDefinitionReader);
		//loadBeanDefinitions方法后面有详细介绍
		loadBeanDefinitions(beanDefinitionReader);
	}

类AbstractXmlApplicationContext：	
	protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
		Resource[] configResources = getConfigResources();
		if (configResources != null) {
			//loadBeanDefinitions方法前面章节有详细说明
			reader.loadBeanDefinitions(configResources);
		}
		String[] configLocations = getConfigLocations();
		if (configLocations != null) {
			//loadBeanDefinitions方法前面章节有详细说明
			reader.loadBeanDefinitions(configLocations);
		}
	}	

6.5 功能拓展

类AbstractApplicationContext：
	protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		// Tell the internal bean factory to use the context's class loader etc.
		//（设置beanFactory的classLoader为当前context的classLoader）
		beanFactory.setBeanClassLoader(getClassLoader());
		//（默认可以使用#{bean.xxx}的形式来调用相关属性值）
		//beanFactory.setBeanExpressionResolver方法不清楚
		beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
		//（为beanFactory增加了一个默认的propertyEditor，这个主要是对bean的属性等设置管理的一个工具）
		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

		// Configure the bean factory with context callbacks.
		//（添加BeanPostProcessor）
		beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
		//（设置了几个忽略自动装配的接口）
		//看：ignoreDependencyInterface方法就把忽略的接口字节码文件加入到map中
		beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
		beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
		beanFactory.ignoreDependencyInterface(EnvironmentAware.class);

		// BeanFactory interface not registered as resolvable type in a plain factory.
		// MessageSource registered (and found for autowiring) as a bean.
		//（设置了几个自动装配的特殊规则）
		//看：ignoreDependencyInterface方法就把注册的接口字节码文件加入到map中		
		beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
		beanFactory.registerResolvableDependency(ResourceLoader.class, this);
		beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
		beanFactory.registerResolvableDependency(ApplicationContext.class, this);

		// Detect a LoadTimeWeaver and prepare for weaving, if found.
		//（增加对AspectJ的支持）
		if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			// Set a temporary ClassLoader for type matching.
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}

		// Register default environment beans.
		//（添加默认的系统环境bean）
		if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
		}
		if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
		}
		if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
		}
	}
6.5.1 增加Spel语言的支持
类AbstractBeanFactory：
	protected Object evaluateBeanDefinitionString(String value, BeanDefinition beanDefinition) {
		if (this.beanExpressionResolver == null) {
			return value;
		}
		Scope scope = (beanDefinition != null ? getRegisteredScope(beanDefinition.getScope()) : null);
		return this.beanExpressionResolver.evaluate(value, new BeanExpressionContext(this, scope));
	}

	
6.5.2 增加属性注册编辑器

pdf中有详细介绍，不记得看看
类ResourceEditorRegistrar：
	public void registerCustomEditors(PropertyEditorRegistry registry) {
		ResourceEditor baseEditor = new ResourceEditor(this.resourceLoader, this.propertyResolver);
		doRegisterEditor(registry, Resource.class, baseEditor);
		doRegisterEditor(registry, ContextResource.class, baseEditor);
		doRegisterEditor(registry, InputStream.class, new InputStreamEditor(baseEditor));
		doRegisterEditor(registry, InputSource.class, new InputSourceEditor(baseEditor));
		doRegisterEditor(registry, File.class, new FileEditor(baseEditor));
		doRegisterEditor(registry, Reader.class, new ReaderEditor(baseEditor));
		doRegisterEditor(registry, URL.class, new URLEditor(baseEditor));

		ClassLoader classLoader = this.resourceLoader.getClassLoader();
		doRegisterEditor(registry, URI.class, new URIEditor(classLoader));
		doRegisterEditor(registry, Class.class, new ClassEditor(classLoader));
		doRegisterEditor(registry, Class[].class, new ClassArrayEditor(classLoader));

		if (this.resourceLoader instanceof ResourcePatternResolver) {
			doRegisterEditor(registry, Resource[].class,
					new ResourceArrayPropertyEditor((ResourcePatternResolver) this.resourceLoader, this.propertyResolver));
		}
	}
类ResourceEditorRegistrar：
	private void doRegisterEditor(PropertyEditorRegistry registry, Class<?> requiredType, PropertyEditor editor) {
		if (registry instanceof PropertyEditorRegistrySupport) {
			((PropertyEditorRegistrySupport) registry).overrideDefaultEditor(requiredType, editor);
		}
		else {
			//registry.registerCustomEditor方法后面有详细介绍
			registry.registerCustomEditor(requiredType, editor);
		}
	}	
	
类PropertyEditorRegistrySupport：
	private void createDefaultEditors() {
		this.defaultEditors = new HashMap<Class<?>, PropertyEditor>(64);

		// Simple editors, without parameterization capabilities.
		// The JDK does not contain a default editor for any of these target types.
		//常用的属性编辑器的配置
		this.defaultEditors.put(Charset.class, new CharsetEditor());
		this.defaultEditors.put(Class.class, new ClassEditor());
		this.defaultEditors.put(Class[].class, new ClassArrayEditor());
		this.defaultEditors.put(Currency.class, new CurrencyEditor());
		this.defaultEditors.put(File.class, new FileEditor());
		this.defaultEditors.put(InputStream.class, new InputStreamEditor());
		this.defaultEditors.put(InputSource.class, new InputSourceEditor());
		this.defaultEditors.put(Locale.class, new LocaleEditor());
		this.defaultEditors.put(Pattern.class, new PatternEditor());
		this.defaultEditors.put(Properties.class, new PropertiesEditor());
		this.defaultEditors.put(Reader.class, new ReaderEditor());
		this.defaultEditors.put(Resource[].class, new ResourceArrayPropertyEditor());
		this.defaultEditors.put(TimeZone.class, new TimeZoneEditor());
		this.defaultEditors.put(URI.class, new URIEditor());
		this.defaultEditors.put(URL.class, new URLEditor());
		this.defaultEditors.put(UUID.class, new UUIDEditor());
		if (zoneIdClass != null) {
			this.defaultEditors.put(zoneIdClass, new ZoneIdEditor());
		}

		// Default instances of collection editors.
		// Can be overridden by registering custom instances of those as custom editors.
		this.defaultEditors.put(Collection.class, new CustomCollectionEditor(Collection.class));
		this.defaultEditors.put(Set.class, new CustomCollectionEditor(Set.class));
		this.defaultEditors.put(SortedSet.class, new CustomCollectionEditor(SortedSet.class));
		this.defaultEditors.put(List.class, new CustomCollectionEditor(List.class));
		this.defaultEditors.put(SortedMap.class, new CustomMapEditor(SortedMap.class));

		// Default editors for primitive arrays.
		this.defaultEditors.put(byte[].class, new ByteArrayPropertyEditor());
		this.defaultEditors.put(char[].class, new CharArrayPropertyEditor());

		// The JDK does not contain a default editor for char!
		this.defaultEditors.put(char.class, new CharacterEditor(false));
		this.defaultEditors.put(Character.class, new CharacterEditor(true));

		// Spring's CustomBooleanEditor accepts more flag values than the JDK's default editor.
		this.defaultEditors.put(boolean.class, new CustomBooleanEditor(false));
		this.defaultEditors.put(Boolean.class, new CustomBooleanEditor(true));

		// The JDK does not contain default editors for number wrapper types!
		// Override JDK primitive number editors with our own CustomNumberEditor.
		this.defaultEditors.put(byte.class, new CustomNumberEditor(Byte.class, false));
		this.defaultEditors.put(Byte.class, new CustomNumberEditor(Byte.class, true));
		this.defaultEditors.put(short.class, new CustomNumberEditor(Short.class, false));
		this.defaultEditors.put(Short.class, new CustomNumberEditor(Short.class, true));
		this.defaultEditors.put(int.class, new CustomNumberEditor(Integer.class, false));
		this.defaultEditors.put(Integer.class, new CustomNumberEditor(Integer.class, true));
		this.defaultEditors.put(long.class, new CustomNumberEditor(Long.class, false));
		this.defaultEditors.put(Long.class, new CustomNumberEditor(Long.class, true));
		this.defaultEditors.put(float.class, new CustomNumberEditor(Float.class, false));
		this.defaultEditors.put(Float.class, new CustomNumberEditor(Float.class, true));
		this.defaultEditors.put(double.class, new CustomNumberEditor(Double.class, false));
		this.defaultEditors.put(Double.class, new CustomNumberEditor(Double.class, true));
		this.defaultEditors.put(BigDecimal.class, new CustomNumberEditor(BigDecimal.class, true));
		this.defaultEditors.put(BigInteger.class, new CustomNumberEditor(BigInteger.class, true));

		// Only register config value editors if explicitly requested.
		if (this.configValueEditorsActive) {
			StringArrayPropertyEditor sae = new StringArrayPropertyEditor();
			this.defaultEditors.put(String[].class, sae);
			this.defaultEditors.put(short[].class, sae);
			this.defaultEditors.put(int[].class, sae);
			this.defaultEditors.put(long[].class, sae);
		}
	}

6.5.3 添加ApplicationContextAwareProcessor处理器

	public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
		AccessControlContext acc = null;

		if (System.getSecurityManager() != null &&
				(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
						bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
						bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
			acc = this.applicationContext.getBeanFactory().getAccessControlContext();
		}

		if (acc != null) {
			AccessController.doPrivileged(new PrivilegedAction<Object>() {
				@Override
				public Object run() {
					//invokeAwareInterfaces方法后面有详细介绍
					//看：实现Aware接口的bean，在初始化后，可以取得对应资源
					invokeAwareInterfaces(bean);
					return null;
				}
			}, acc);
		}
		else {
			//invokeAwareInterfaces方法后面有详细介绍
			invokeAwareInterfaces(bean);
		}

		return bean;
	}	

6.5.4 设置忽略依赖

		beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
		beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
		beanFactory.ignoreDependencyInterface(EnvironmentAware.class);


6.5.5 注册依赖

		beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
		beanFactory.registerResolvableDependency(ResourceLoader.class, this);
		beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
		beanFactory.registerResolvableDependency(ApplicationContext.class, this);
		

6.6 BeanFactory的后处理

6.6.1 激活注册的BeanFactoryPostProcessor


		
	public static void invokeBeanFactoryPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

		// Invoke BeanDefinitionRegistryPostProcessors first, if any.
		Set<String> processedBeans = new HashSet<String>();

		//（对BeanDefinitionRegistry类型的处理）
		if (beanFactory instanceof BeanDefinitionRegistry) {
			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
			List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
			//（BeanDefinitionRegistryPostProcessor）
			List<BeanDefinitionRegistryPostProcessor> registryPostProcessors =
					new LinkedList<BeanDefinitionRegistryPostProcessor>();
			//（硬编码注册的后处理器）
			//测试：beanFactoryPostProcessors：[]
			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					BeanDefinitionRegistryPostProcessor registryPostProcessor =
							(BeanDefinitionRegistryPostProcessor) postProcessor;
					//（对于BeanDefinitionRegistryPostProcessor类型，在BeanFactoryPostProcessor的基础上还有自己定义的方法，需要先调用）
					registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
					registryPostProcessors.add(registryPostProcessor);
				}
				else {
					//（记录常规BeanFactoryPostProcessor）
					regularPostProcessors.add(postProcessor);
				}
			}

			// Do not initialize FactoryBeans here: We need to leave all regular beans
			// uninitialized to let the bean factory post-processors apply to them!
			// Separate between BeanDefinitionRegistryPostProcessors that implement
			// PriorityOrdered, Ordered, and the rest.
			//（对于配置中读取的BeanFactoryPostProcessor的处理）
			//测试：postProcessorNames：[]
			String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);

			// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
			List<BeanDefinitionRegistryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
			
			for (String ppName : postProcessorNames) {
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
					priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			//（按照优先级进行排序）
			sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
			registryPostProcessors.addAll(priorityOrderedPostProcessors);
			invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry);

			// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
			//测试：postProcessorNames：[]
			postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			List<BeanDefinitionRegistryPostProcessor> orderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
			//（对后处理器进行分类）
			for (String ppName : postProcessorNames) {
				if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
					orderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			sortPostProcessors(beanFactory, orderedPostProcessors);
			registryPostProcessors.addAll(orderedPostProcessors);
			invokeBeanDefinitionRegistryPostProcessors(orderedPostProcessors, registry);

			// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
			boolean reiterate = true;
			while (reiterate) {
				reiterate = false;
				//测试：postProcessorNames：[]
				postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
				for (String ppName : postProcessorNames) {
					if (!processedBeans.contains(ppName)) {
						BeanDefinitionRegistryPostProcessor pp = beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class);
						registryPostProcessors.add(pp);
						processedBeans.add(ppName);
						pp.postProcessBeanDefinitionRegistry(registry);
						reiterate = true;
					}
				}
			}

			// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
			invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
			invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
		}

		else {
			// Invoke factory processors registered with the context instance.
			invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
		}

		// Do not initialize FactoryBeans here: We need to leave all regular beans
		// uninitialized to let the bean factory post-processors apply to them!
		//测试：postProcessorNames：org.springframework.beans.factory.config.CustomEditorConfigurer#0
		String[] postProcessorNames =
				beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

		// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
		// Ordered, and the rest.
		List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
		List<String> orderedPostProcessorNames = new ArrayList<String>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
		for (String ppName : postProcessorNames) {
			if (processedBeans.contains(ppName)) {
				// skip - already processed in first phase above
			}
			else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
			}
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				//测试：进入这里
				orderedPostProcessorNames.add(ppName);
			}
			else {
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

		// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
		//（按照优先级进行排序）
		sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
		invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

		// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
		List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
		for (String postProcessorName : orderedPostProcessorNames) {
			orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		//（按照order排序）
		sortPostProcessors(beanFactory, orderedPostProcessors);
		invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

		// Finally, invoke all other BeanFactoryPostProcessors.
		//（无序，直接调用）
		List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
		for (String postProcessorName : nonOrderedPostProcessorNames) {
			nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

		// Clear cached merged bean definitions since the post-processors might have
		// modified the original metadata, e.g. replacing placeholders in values...
		beanFactory.clearMetadataCache();
	}

6.6.2 注册BeanPostProcessor
	
	public static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

		//测试：postProcessorNames：[com.dodi.spring.beanPostProcessor.MyInstantiationAwareBeanPostProcessor#0]	
		String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

		// Register BeanPostProcessorChecker that logs an info message when
		// a bean is created during BeanPostProcessor instantiation, i.e. when
		// a bean is not eligible for getting processed by all BeanPostProcessors.
		//（BeanPostProcessorChecker是一个普通的信息打印，可能会有些情况
		//当Spring的配置中的后处理器还没有被注册就已经开始了bean的初始化时
		//便会打印出BeanPostProcessorChecker中设定的信息）
		//测试：beanProcessorTargetCount：3
		int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
		beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

		// Separate between BeanPostProcessors that implement PriorityOrdered,
		// Ordered, and the rest.
		//（使用PriorityOrdered保证顺序）
		List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
		//（MergedBeanDefinitionPostProcessor）
		List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
		//（使用Ordered保证顺序）
		List<String> orderedPostProcessorNames = new ArrayList<String>();
		//（无序BeanPostProcessor）
		List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
		for (String ppName : postProcessorNames) {
			if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
				priorityOrderedPostProcessors.add(pp);
				if (pp instanceof MergedBeanDefinitionPostProcessor) {
					internalPostProcessors.add(pp);
				}
			}
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			}
			else {
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

		// First, register the BeanPostProcessors that implement PriorityOrdered.
		//（第一步，注册所有实现PriorityOrdered的BeanPostProcessor）
		sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
		registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

		// Next, register the BeanPostProcessors that implement Ordered.
		//（第二步，注册所有实现Ordered的BeanPostProcessor）
		List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();
		for (String ppName : orderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			orderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		sortPostProcessors(beanFactory, orderedPostProcessors);
		registerBeanPostProcessors(beanFactory, orderedPostProcessors);

		// Now, register all regular BeanPostProcessors.
		//（第三步，注册所有无序的BeanPostProcessor）
		List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
		for (String ppName : nonOrderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			nonOrderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		//看：registerBeanPostProcessors方法把nonOrderedPostProcessors放入到map中
		//测试：nonOrderedPostProcessors：[com.dodi.spring.beanPostProcessor.MyInstantiationAwareBeanPostProcessor@7cc0cdad]
		registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

		// Finally, re-register all internal BeanPostProcessors.
		//（第四步，注册所有MergedBeanDefinitionPostProcessor类型的BeanPostProcessor，并非重复注册）
		//（在beanFactory.addBeanPostProcessor中会先移除已经存在的BeanPostProcessor）
		sortPostProcessors(beanFactory, internalPostProcessors);
		registerBeanPostProcessors(beanFactory, internalPostProcessors);

		//（添加ApplicationListener探测器）
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
	}
	
	private static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {

		for (BeanPostProcessor postProcessor : postProcessors) {
			beanFactory.addBeanPostProcessor(postProcessor);
		}
	}
	
	public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
		Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
		this.beanPostProcessors.remove(beanPostProcessor);
		this.beanPostProcessors.add(beanPostProcessor);
		if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
			this.hasInstantiationAwareBeanPostProcessors = true;
		}
		if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
			this.hasDestructionAwareBeanPostProcessors = true;
		}
	}


6.6.3 初始化消息资源

类AbstractApplicationContext：
	protected void initMessageSource() {
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
			//（如果在配置中已经配置了messageSource，那么将messageSource提取并记录在this.messageSource中）
			//看：从beanFactory中获得messageSource的bean放到当前成员变量中，便于后面使用
			this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
			// Make MessageSource aware of parent MessageSource.
			//测试时以下判断没进入
			if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
				HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
				if (hms.getParentMessageSource() == null) {
					// Only set parent context as parent MessageSource if no parent MessageSource
					// registered already.
					hms.setParentMessageSource(getInternalParentMessageSource());
				}
			}
			if (logger.isDebugEnabled()) {
				logger.debug("Using MessageSource [" + this.messageSource + "]");
			}
		}
		else {
			// Use empty MessageSource to be able to accept getMessage calls.
			//（如果用户并没有定义配置文件，那么使用临时的DelegatingMessageSource以便于作为调用getMessage方法的返回）
			DelegatingMessageSource dms = new DelegatingMessageSource();
			dms.setParentMessageSource(getInternalParentMessageSource());
			this.messageSource = dms;
			beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
			if (logger.isDebugEnabled()) {
				logger.debug("Unable to locate MessageSource with name '" + MESSAGE_SOURCE_BEAN_NAME +
						"': using default [" + this.messageSource + "]");
			}
		}
	}

	public String getMessage(String code, Object args[], Locale locale) throws NoSuchMessageException {
		//看：里面封装的是MessageFormat的处理
		return getMessageSource().getMessage(code, args, locale);
	}

6.6.4 初始化ApplicationEventMulticaster

类AbstractApplicationContext：
	protected void initApplicationEventMulticaster() {
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		//（用户自定义了事件广播器，那么使用用户自定义的事件广播器）
		if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
			this.applicationEventMulticaster =
					beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
			if (logger.isDebugEnabled()) {
				logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
			}
		}
		else {
			//（用户没有自定义事件广播器，那么使用默认的ApplicationEvenMulticaster）
			//测试进入这里
			this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
			//看：就注册到map中
			beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
			if (logger.isDebugEnabled()) {
				logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
						APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
						"': using default [" + this.applicationEventMulticaster + "]");
			}
		}
	}
类SimpleApplicationEventMulticaster：
	protected void invokeListener(ApplicationListener listener, ApplicationEvent event) {
		ErrorHandler errorHandler = getErrorHandler();
		if (errorHandler != null) {
			try {
				listener.onApplicationEvent(event);
			}
			catch (Throwable err) {
				errorHandler.handleError(err);
			}
		}
		else {
			//从获得的监听器调用重写的方法进行处理
			listener.onApplicationEvent(event);
		}
	}	

类AbstractApplicationContext：
	protected void registerListeners() {
		// Register statically specified listeners first.
		//（硬编码方式注册的监听器处理）
		for (ApplicationListener<?> listener : getApplicationListeners()) {
			getApplicationEventMulticaster().addApplicationListener(listener);
		}

		// Do not initialize FactoryBeans here: We need to leave all regular beans
		// uninitialized to let post-processors apply to them!
		//（配置文件注册的监听器处理）
		//测试：listenerBeanNames：[testListener]
		String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
		for (String listenerBeanName : listenerBeanNames) {
			//添加到Listener的set集合中
			getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
		}

		// Publish early application events now that we finally have a multicaster...
		//测试：earlyEventsToProcess：[]
		Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
		this.earlyApplicationEvents = null;
		if (earlyEventsToProcess != null) {
			for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
				getApplicationEventMulticaster().multicastEvent(earlyEvent);
			}
		}
	}

6.7 初始化非延迟加载单例

类AbstractApplicationContext：
	protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// Initialize conversion service for this context.
		if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
				beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
			//猜：判断是否为ConversionService类，设置为
			beanFactory.setConversionService(
					beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
		}

		// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
		String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
		for (String weaverAwareName : weaverAwareNames) {
			getBean(weaverAwareName);
		}

		// Stop using the temporary ClassLoader for type matching.
		beanFactory.setTempClassLoader(null);

		// Allow for caching all bean definition metadata, not expecting further changes.
		//（冻结所有的bean定义，说明注册的bean定义将不被修改或任何进一步的处理）
		beanFactory.freezeConfiguration();

		// Instantiate all remaining (non-lazy-init) singletons.
		//（初始化剩下的单实例）
		beanFactory.preInstantiateSingletons();
	}

1. ConversionService的设置


2. 冻结配置

类DefaultListableBeanFactory：
	public void freezeConfiguration() {
		//把冻结状态设置为true
		this.configurationFrozen = true;
		//获得所有bean，设置到冻结bean中
		this.frozenBeanDefinitionNames = StringUtils.toStringArray(this.beanDefinitionNames);
	}

3. 初始化非延迟加载

类DefaultListableBeanFactory：
	public void preInstantiateSingletons() throws BeansException {
		if (this.logger.isDebugEnabled()) {
			this.logger.debug("Pre-instantiating singletons in " + this);
		}

		// Iterate over a copy to allow for init methods which in turn register new bean definitions.
		// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
		List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);

		// Trigger initialization of all non-lazy singleton beans...
		for (String beanName : beanNames) {
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				if (isFactoryBean(beanName)) {
					final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
					boolean isEagerInit;
					if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
						isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
							@Override
							public Boolean run() {
								return ((SmartFactoryBean<?>) factory).isEagerInit();
							}
						}, getAccessControlContext());
					}
					else {
						isEagerInit = (factory instanceof SmartFactoryBean &&
								((SmartFactoryBean<?>) factory).isEagerInit());
					}
					if (isEagerInit) {
						getBean(beanName);
					}
				}
				else {
					getBean(beanName);
				}
			}
		}

		// Trigger post-initialization callback for all applicable beans...
		for (String beanName : beanNames) {
			Object singletonInstance = getSingleton(beanName);
			if (singletonInstance instanceof SmartInitializingSingleton) {
				final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
				if (System.getSecurityManager() != null) {
					AccessController.doPrivileged(new PrivilegedAction<Object>() {
						@Override
						public Object run() {
							smartSingleton.afterSingletonsInstantiated();
							return null;
						}
					}, getAccessControlContext());
				}
				else {
					smartSingleton.afterSingletonsInstantiated();
				}
			}
		}
	}
	
	
6.8 finishRefresh

	protected void finishRefresh() {
		// Initialize lifecycle processor for this context.
		initLifecycleProcessor();

		// Propagate refresh to lifecycle processor first.
		getLifecycleProcessor().onRefresh();

		// Publish the final event.
		publishEvent(new ContextRefreshedEvent(this));

		// Participate in LiveBeansView MBean, if active.
		LiveBeansView.registerApplicationContext(this);
	}

1.//初始化生命周期类LifecycleProcessor
	
	protected void initLifecycleProcessor() {
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
			this.lifecycleProcessor =
					beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
			if (logger.isDebugEnabled()) {
				logger.debug("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
			}
		}
		else {
			//初始化生命周期类LifecycleProcessor
			DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
			defaultProcessor.setBeanFactory(beanFactory);
			this.lifecycleProcessor = defaultProcessor;
			//注册生命周期类LifecycleProcessor
			beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
			if (logger.isDebugEnabled()) {
				logger.debug("Unable to locate LifecycleProcessor with name '" +
						LIFECYCLE_PROCESSOR_BEAN_NAME +
						"': using default [" + this.lifecycleProcessor + "]");
			}
		}
	}	


2. 	启动所有实现了Lifecycle接口的bean

	public void onRefresh() {
		startBeans(true);
		this.running = true;
	}

	private void startBeans(boolean autoStartupOnly) {
		Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
		Map<Integer, LifecycleGroup> phases = new HashMap<Integer, LifecycleGroup>();
		for (Map.Entry<String, ? extends Lifecycle> entry : lifecycleBeans.entrySet()) {
			Lifecycle bean = entry.getValue();
			if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {
				int phase = getPhase(bean);
				LifecycleGroup group = phases.get(phase);
				if (group == null) {
					group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly);
					phases.put(phase, group);
				}
				group.add(entry.getKey(), bean);
			}
		}
		if (phases.size() > 0) {
			List<Integer> keys = new ArrayList<Integer>(phases.keySet());
			Collections.sort(keys);
			for (Integer key : keys) {
				phases.get(key).start();
			}
		}
	}	

	protected void publishEvent(Object event, ResolvableType eventType) {
		Assert.notNull(event, "Event must not be null");
		if (logger.isTraceEnabled()) {
			logger.trace("Publishing event in " + getDisplayName() + ": " + event);
		}

		// Decorate event as an ApplicationEvent if necessary
		ApplicationEvent applicationEvent;
		if (event instanceof ApplicationEvent) {
			applicationEvent = (ApplicationEvent) event;
		}
		else {
			applicationEvent = new PayloadApplicationEvent<Object>(this, event);
			if (eventType == null) {
				eventType = ResolvableType.forClassWithGenerics(PayloadApplicationEvent.class, event.getClass());
			}
		}

		// Multicast right now if possible - or lazily once the multicaster is initialized
		if (this.earlyApplicationEvents != null) {
			this.earlyApplicationEvents.add(applicationEvent);
		}
		else {
			getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
		}

		// Publish event via parent context as well...
		if (this.parent != null) {
			if (this.parent instanceof AbstractApplicationContext) {
				((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
			}
			else {
				this.parent.publishEvent(event);
			}
		}
	}

	
	
	
	

	
第七章 	AOP


7.2 动态AOP自定义标签

类AopNamespaceHandler：
	public void init() {
		// In 2.0 XSD as well as in 2.1 XSD.
		registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());
		//aspectj-autoproxy，开启aop的注解
		registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());
		registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator());

		// Only in 2.0 XSD: moved to context namespace as of 2.1
		registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
	}

7.2.1 注册AnnotationAwareAspectJAutoProxyCreator

类AspectJAutoProxyBeanDefinitionParser：
	public BeanDefinition parse(Element element, ParserContext parserContext) {
		//（注册AnnotationAwareAspectJAutoProxyCreator）
		//registerAspectJAnnotationAutoProxyCreatorIfNecessary方法后面有详细介绍
		AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);
		//（对于注解中子类的处理）
		extendBeanDefinition(element, parserContext);
		return null;
	}	

类AopNamespaceUtils：

	//（注册AnnotationAwareAspectJAutoProxyCreator）
	public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary(
			ParserContext parserContext, Element sourceElement) {

		//（注册或升级AutoProxyCreator定义beanName为org.Springframework.aop.config.internal.AutoProxyCreator
		//的BeanDefinition）
		//registerAspectJAnnotationAutoProxyCreatorIfNecessary方法后面有详细介绍
		BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(
				parserContext.getRegistry(), parserContext.extractSource(sourceElement));
		//（对于proxy-target-class以及expose-proxy属性的处理）
		//useClassProxyingIfNecessary方法后面有详细介绍
		useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
		//（注册组件并通知，便于监听器做进一步处理）
		//（其中beanDefinition的className为AnnotationAwareAspectJAutoProxyCreator）
		registerComponentIfNecessary(beanDefinition, parserContext);
	}

1. 注册或者升级AnnotationAwareAspectJAutoProxyCreator	

类AopConfigUtils：	
	public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
		//（AOP的实现都是通过AnnotationAwareAspectJAutoProxyCreator实现）
		return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
	}

类AopConfigUtils：	
	private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) {
		Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
		//（如果已经存在了自动代理创建器且存在的自动代理创建器与现在的不一致
		//那么需要根据优先级来判断到底需要使用哪种）
		//测试：AUTO_PROXY_CREATOR_BEAN_NAME：org.springframework.aop.config.internalAutoProxyCreator
		if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
			BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
			if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
				int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
				int requiredPriority = findPriorityForClass(cls);
				if (currentPriority < requiredPriority) {
					//（改变bean最重要的就是改变bean所对应的className属性）
					apcDefinition.setBeanClassName(cls.getName());
				}
			}
			//（如果已经存在自动代理创建器并且与将要创建的一致，那么无需在此创建）
			return null;
		}
		测试：cls：class org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator
		RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
		//测试：source：null
		beanDefinition.setSource(source);
		//测试：Ordered.HIGHEST_PRECEDENCE：-2147483648
		beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
		//测试：BeanDefinition.ROLE_INFRASTRUCTURE：2
		beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
		//registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition)方法后面有详细介绍
		//测试：在map中注册
		//registry.registerBeanDefinition方法具体不清楚
		registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
		return beanDefinition;
	}

2. 处理proxy-target-class以及expose-proxy属性	

proxy-target-class="true"和proxy-target-class="false"的区别，为true则是基于类的代理将起作用（需要cglib库），为false或者省略这个属性，则标准的JDK 基于接口的代理将起作用。	

expose-proxy：解决类方法内部调用方法无法增强问题
	
类AopNamespaceUtils：	
	private static void useClassProxyingIfNecessary(BeanDefinitionRegistry registry, Element sourceElement) {
		if (sourceElement != null) {
			//（对于proxy-target-class属性的处理）
			//测试：PROXY_TARGET_CLASS_ATTRIBUTE：proxy-target-class；proxyTargetClass：false
			boolean proxyTargetClass = Boolean.valueOf(sourceElement.getAttribute(PROXY_TARGET_CLASS_ATTRIBUTE));
			if (proxyTargetClass) {
				//forceAutoProxyCreatorToUseClassProxying方法后面有详细介绍
				AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
			}
			//（对于expose-proxy属性的处理）
			//测试：EXPOSE_PROXY_ATTRIBUTE：expose-proxy；false
			boolean exposeProxy = Boolean.valueOf(sourceElement.getAttribute(EXPOSE_PROXY_ATTRIBUTE));
			if (exposeProxy) {
				//forceAutoProxyCreatorToExposeProxy方法后面有详细介绍
				AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
			}
		}
	}
	类AopConfigUtils：
	//（强制使用的过程其实也是一个属性设置的过程）
	public static void forceAutoProxyCreatorToUseClassProxying(BeanDefinitionRegistry registry) {
		//猜：判断容器中是否有org.springframework.aop.config.internalAutoProxyCreator的bean存在
		//测试：AUTO_PROXY_CREATOR_BEAN_NAME：org.springframework.aop.config.internalAutoProxyCreator
		if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
			//从容器中获得org.springframework.aop.config.internalAutoProxyCreator此bean
			BeanDefinition definition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
			//definition设置property中的值为true
			definition.getPropertyValues().add("proxyTargetClass", Boolean.TRUE);
		}
	}
	类AopConfigUtils：
	//看；与上一方法基本一样
	static void forceAutoProxyCreatorToExposeProxy(BeanDefinitionRegistry registry) {
		if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
			BeanDefinition definition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
			definition.getPropertyValues().add("exposeProxy", Boolean.TRUE);
		}
	}
	
7.3 创建AOP代理
	类：
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		if (bean != null) {
			//（根据给定的bean的class和name构建出个key，格式：beanClassName_beanName）
			//getCacheKey方法判断是否为工厂类
			//测试：cacheKey：testBean
			//getCacheKey方法不清楚
			Object cacheKey = getCacheKey(bean.getClass(), beanName);
			if (!this.earlyProxyReferences.contains(cacheKey)) {
				//（如果它合适被代理，则需要封装指定bean）
				//wrapIfNecessary方法后面有详细介绍
				return wrapIfNecessary(bean, beanName, cacheKey);
			}
		}
		return bean;
	}
	
	protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
		//（如果已经处理过）
		//测试：判断没进
		if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
			return bean;
		}
		//（无需增强）
		//测试：判断没进
		if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
			return bean;
		}
		//（给定的bean类是否代表一个基础设施类，基础设施类不应代理，或者配置了指定bean不需自动代理）
		////测试：判断没进
		if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
			this.advisedBeans.put(cacheKey, Boolean.FALSE);
			return bean;
		}

		// Create proxy if we have advice.
		//（如果存在增强方法则创建代理）
		//getAdvicesAndAdvisorsForBean方法后面有详细介绍
		Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
		//（如果获取到了增强则需要针对增强创建代理）
		if (specificInterceptors != DO_NOT_PROXY) {
			this.advisedBeans.put(cacheKey, Boolean.TRUE);
			//（创建代理）
			//createProxy方法后面有详细介绍
			Object proxy = createProxy(
					bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
			this.proxyTypes.put(cacheKey, proxy.getClass());
			return proxy;
		}

		this.advisedBeans.put(cacheKey, Boolean.FALSE);
		return bean;
	}

	protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {
		
		//findEligibleAdvisors方法后面有详细介绍
		List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
		if (advisors.isEmpty()) {
			return DO_NOT_PROXY;
		}
		return advisors.toArray();
	}
	
	类AbstractAdvisorAutoProxyCreator：
	protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
		//findCandidateAdvisors方法后面有详细介绍
		List<Advisor> candidateAdvisors = findCandidateAdvisors();
		//findAdvisorsThatCanApply方法后面有详细介绍
		List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
		extendAdvisors(eligibleAdvisors);
		if (!eligibleAdvisors.isEmpty()) {
			eligibleAdvisors = sortAdvisors(eligibleAdvisors);
		}
		return eligibleAdvisors;
	}	

7.3.1 获取增强器
	类AnnotationAwareAspectJAutoProxyCreator：
	protected List<Advisor> findCandidateAdvisors() {
		// Add all the Spring advisors found according to superclass rules.
		//测试：advisors：[]
		List<Advisor> advisors = super.findCandidateAdvisors();
		// Build Advisors for all AspectJ aspects in the bean factory.
		//advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors())方法后面有详细介绍
		advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
		return advisors;
	}

	类BeanFactoryAspectJAdvisorsBuilder：
	public List<Advisor> buildAspectJAdvisors() {
		List<String> aspectNames = null;

		synchronized (this) {
			aspectNames = this.aspectBeanNames;
			//测试：aspectNames：[com.dodi.spring.aop.AspectJTest#0]
			if (aspectNames == null) {
				List<Advisor> advisors = new LinkedList<Advisor>();
				aspectNames = new LinkedList<String>();
				//（获取所有的beanName）
				String[] beanNames =
						BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Object.class, true, false);
				//（循环所有的beanName找出对应的增强方法）
				for (String beanName : beanNames) {
					//（不合法的bean则略过，由子类定义规则，默认返回true）
					if (!isEligibleBean(beanName)) {
						continue;
					}
					// We must be careful not to instantiate beans eagerly as in this
					// case they would be cached by the Spring container but would not
					// have been weaved
					//（获取对应的bean的类型）
					Class<?> beanType = this.beanFactory.getType(beanName);
					if (beanType == null) {
						continue;
					}
					//（如果存在Aspect注解）
					if (this.advisorFactory.isAspect(beanType)) {
						aspectNames.add(beanName);
						AspectMetadata amd = new AspectMetadata(beanType, beanName);
						if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
							MetadataAwareAspectInstanceFactory factory =
									new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
							//（解析标记AspectJ注解中的增强方法）
							//this.advisorFactory.getAdvisors(factory)方法后面有详细介绍
							List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
							if (this.beanFactory.isSingleton(beanName)) {
								this.advisorsCache.put(beanName, classAdvisors);
							}
							else {
								this.aspectFactoryCache.put(beanName, factory);
							}
							advisors.addAll(classAdvisors);
						}
						else {
							// Per target or per this.
							if (this.beanFactory.isSingleton(beanName)) {
								throw new IllegalArgumentException("Bean with name '" + beanName +
										"' is a singleton, but aspect instantiation model is not singleton");
							}
							MetadataAwareAspectInstanceFactory factory =
									new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
							this.aspectFactoryCache.put(beanName, factory);
							advisors.addAll(this.advisorFactory.getAdvisors(factory));
						}
					}
				}
				this.aspectBeanNames = aspectNames;
				return advisors;
			}
		}

		if (aspectNames.isEmpty()) {
			return Collections.emptyList();
		}
		//（记录在缓存中）
		List<Advisor> advisors = new LinkedList<Advisor>();
		for (String aspectName : aspectNames) {
			List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
			if (cachedAdvisors != null) {
				advisors.addAll(cachedAdvisors);
			}
			else {
				MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
				advisors.addAll(this.advisorFactory.getAdvisors(factory));
			}
		}
		return advisors;
	}
	
	
	
	
	
第8章 数据库连接JDBC

8.2 save/update功能的实现

	类JdbcTemplate：
	@Override
	public int update(String sql, PreparedStatementSetter pss) throws DataAccessException {
		return update(new SimplePreparedStatementCreator(sql), pss);
	}
	类JdbcTemplate：
	@Override
	public int update(String sql, Object[] args, int[] argTypes) throws DataAccessException {
		return update(sql, newArgTypePreparedStatementSetter(args, argTypes));
	}	
	类JdbcTemplate：	
	protected int update(final PreparedStatementCreator psc, final PreparedStatementSetter pss)
			throws DataAccessException {

		logger.debug("Executing prepared SQL update");
		return execute(psc, new PreparedStatementCallback<Integer>() {
			@Override
			public Integer doInPreparedStatement(PreparedStatement ps) throws SQLException {
				try {
					if (pss != null) {
						//（设置PreparedStatement所需的全部参数）
						//setValues方法后面有详细介绍
						pss.setValues(ps);
					}
					//执行更新
					int rows = ps.executeUpdate();
					if (logger.isDebugEnabled()) {
						logger.debug("SQL update affected " + rows + " rows");
					}
					return rows;
				}
				finally {
					if (pss instanceof ParameterDisposer) {
						((ParameterDisposer) pss).cleanupParameters();
					}
				}
			}
		});
	}	

8.2.1 基础方法execute
	
	类JdbcTemplate：
	@Override
	public <T> T execute(PreparedStatementCreator psc, PreparedStatementCallback<T> action)
			throws DataAccessException {

		Assert.notNull(psc, "PreparedStatementCreator must not be null");
		Assert.notNull(action, "Callback object must not be null");
		if (logger.isDebugEnabled()) {
			String sql = getSql(psc);
			logger.debug("Executing prepared SQL statement" + (sql != null ? " [" + sql + "]" : ""));
		}

		//（获取数据库连接）
		//getConnection方法后面有详细介绍
		Connection con = DataSourceUtils.getConnection(getDataSource());
		PreparedStatement ps = null;
		try {
			Connection conToUse = con;
			if (this.nativeJdbcExtractor != null &&
					this.nativeJdbcExtractor.isNativeConnectionNecessaryForNativePreparedStatements()) {
				conToUse = this.nativeJdbcExtractor.getNativeConnection(con);
			}
			ps = psc.createPreparedStatement(conToUse);
			//（应用用户设定的输入参数）
			//applyStatementSettings方法后面有详细介绍
			applyStatementSettings(ps);
			PreparedStatement psToUse = ps;
			//测试：判断没进
			if (this.nativeJdbcExtractor != null) {
				psToUse = this.nativeJdbcExtractor.getNativePreparedStatement(ps);
			}

			T result = action.doInPreparedStatement(psToUse);
			//（调用回调函数）
			//handleWarnings方法后面有详细介绍
			handleWarnings(ps);
			return result;
		}
		catch (SQLException ex) {
			// Release Connection early, to avoid potential connection pool deadlock
			// in the case when the exception translator hasn't been initialized yet.
			//（释放数据库连接避免当异常转换器没有被初始化的时候出现潜在的连接池死锁）
			if (psc instanceof ParameterDisposer) {
				((ParameterDisposer) psc).cleanupParameters();
			}
			String sql = getSql(psc);
			psc = null;
			JdbcUtils.closeStatement(ps);
			ps = null;
			//releaseConnection方法后面有详细介绍
			DataSourceUtils.releaseConnection(con, getDataSource());
			con = null;
			throw getExceptionTranslator().translate("PreparedStatementCallback", sql, ex);
		}
		finally {
			//测试没进判断）
			if (psc instanceof ParameterDisposer) {
				((ParameterDisposer) psc).cleanupParameters();
			}
			
			JdbcUtils.closeStatement(ps);
			//
			DataSourceUtils.releaseConnection(con, getDataSource());
		}
	}	
	
1.获取数据库连接	

	类DataSourceUtils：
		public static Connection doGetConnection(DataSource dataSource) throws SQLException {
		Assert.notNull(dataSource, "No DataSource specified");

		//测试：conHolder:null
		ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource);
		//判断没进
		//猜：可能是缓存
		if (conHolder != null && (conHolder.hasConnection() || conHolder.isSynchronizedWithTransaction())) {
			conHolder.requested();
			if (!conHolder.hasConnection()) {
				logger.debug("Fetching resumed JDBC Connection from DataSource");
				conHolder.setConnection(dataSource.getConnection());
			}
			return conHolder.getConnection();
		}
		// Else we either got no holder or an empty thread-bound holder here.

		logger.debug("Fetching JDBC Connection from DataSource");
		Connection con = dataSource.getConnection();

		//（当前线程支持同步）
		//测试：判断没进
		if (TransactionSynchronizationManager.isSynchronizationActive()) {
			logger.debug("Registering transaction synchronization for JDBC Connection");
			// Use same Connection for further JDBC actions within the transaction.
			// Thread-bound object will get removed by synchronization at transaction completion.
			//（在事务中使用同一数据库连接）
			ConnectionHolder holderToUse = conHolder;
			if (holderToUse == null) {
				holderToUse = new ConnectionHolder(con);
			}
			else {
				//（记录数据库连接）
				holderToUse.setConnection(con);
			}
			holderToUse.requested();
			TransactionSynchronizationManager.registerSynchronization(
					new ConnectionSynchronization(holderToUse, dataSource));
			holderToUse.setSynchronizedWithTransaction(true);
			if (holderToUse != conHolder) {
				TransactionSynchronizationManager.bindResource(dataSource, holderToUse);
			}
		}

		return con;
	}
	
2.应用用户设定的输入参数

	protected void applyStatementSettings(Statement stmt) throws SQLException {
		//测试：fetchSize:-1
		int fetchSize = getFetchSize();
		if (fetchSize >= 0) {
			//setFetchSize方法看pdf
			stmt.setFetchSize(fetchSize);
		}
		//测试：maxRows:-1
		int maxRows = getMaxRows();
		if (maxRows >= 0) {
			//setMaxRows方法看pdf
			stmt.setMaxRows(maxRows);
		}
		DataSourceUtils.applyTimeout(stmt, getDataSource(), getQueryTimeout());
	}	
	
3.调用回调函数	

代码在上面	
	
4.警告处理
	protected void handleWarnings(Statement stmt) throws SQLException {
		//（当设置为忽略警告时只尝试打印日志）
		if (isIgnoreWarnings()) {
			if (logger.isDebugEnabled()) {
				//（如果日志开启的情况下打印日志）
				SQLWarning warningToLog = stmt.getWarnings();
				while (warningToLog != null) {
					logger.debug("SQLWarning ignored: SQL state '" + warningToLog.getSQLState() + "', error code '" +
							warningToLog.getErrorCode() + "', message [" + warningToLog.getMessage() + "]");
					warningToLog = warningToLog.getNextWarning();
				}
			}
		}
		else {
			handleWarnings(stmt.getWarnings());
		}
	}	

5.资源释放
	public static void doReleaseConnection(Connection con, DataSource dataSource) throws SQLException {
		if (con == null) {
			return;
		}
		if (dataSource != null) {
			//（当前线程存在事务的情况下说明存在共用数据库连接直接使用ConnectionHolder中的
			//released方法进行连接数减一而不是真正的释放连接）
			ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource);
			//判断没进
			if (conHolder != null && connectionEquals(conHolder, con)) {
				// It's the transactional Connection: Don't close it.
				conHolder.released();
				return;
			}
		}
		logger.debug("Returning JDBC Connection to DataSource");
		doCloseConnection(con, dataSource);
	}

8.2.2 Update中的回调函数

	类ArgumentTypePreparedStatementSetter：
	@Override
	public void setValues(PreparedStatement ps) throws SQLException {
		int parameterPosition = 1;
		if (this.args != null) {
			//（遍历每个参数以作为类型匹配及转换）
			for (int i = 0; i < this.args.length; i++) {
				Object arg = this.args[i];
				//（如果是集合类则需要进入集合类内部递归解析集合内部属性）
				if (arg instanceof Collection && this.argTypes[i] != Types.ARRAY) {
					Collection<?> entries = (Collection<?>) arg;
					for (Object entry : entries) {
						if (entry instanceof Object[]) {
							Object[] valueArray = ((Object[]) entry);
							for (Object argValue : valueArray) {
								doSetValue(ps, parameterPosition, this.argTypes[i], argValue);
								parameterPosition++;
							}
						}
						else {
							doSetValue(ps, parameterPosition, this.argTypes[i], entry);
							parameterPosition++;
						}
					}
				}
				else {
					//（解析当前属性）
					doSetValue(ps, parameterPosition, this.argTypes[i], arg);
					parameterPosition++;
				}
			}
		}
	}
	
	类StatementCreatorUtils：
	protected void doSetValue(PreparedStatement ps, int parameterPosition, int argType, Object argValue)
			throws SQLException {

		StatementCreatorUtils.setParameterValue(ps, parameterPosition, argType, argValue);
	}	
	
	类StatementCreatorUtils：
	public static void setParameterValue(PreparedStatement ps, int paramIndex, int sqlType, Object inValue)
			throws SQLException {

		setParameterValueInternal(ps, paramIndex, sqlType, null, null, inValue);
	}

	类StatementCreatorUtils：
	private static void setParameterValueInternal(PreparedStatement ps, int paramIndex, int sqlType,
			String typeName, Integer scale, Object inValue) throws SQLException {

		String typeNameToUse = typeName;
		int sqlTypeToUse = sqlType;
		Object inValueToUse = inValue;

		// override type info?
		//判断没进
		if (inValue instanceof SqlParameterValue) {
			SqlParameterValue parameterValue = (SqlParameterValue) inValue;
			if (logger.isDebugEnabled()) {
				logger.debug("Overriding type info with runtime info from SqlParameterValue: column index " + paramIndex +
						", SQL type " + parameterValue.getSqlType() + ", type name " + parameterValue.getTypeName());
			}
			if (parameterValue.getSqlType() != SqlTypeValue.TYPE_UNKNOWN) {
				sqlTypeToUse = parameterValue.getSqlType();
			}
			if (parameterValue.getTypeName() != null) {
				typeNameToUse = parameterValue.getTypeName();
			}
			inValueToUse = parameterValue.getValue();
		}

		if (logger.isTraceEnabled()) {
			logger.trace("Setting SQL statement parameter value: column index " + paramIndex +
					", parameter value [" + inValueToUse +
					"], value class [" + (inValueToUse != null ? inValueToUse.getClass().getName() : "null") +
					"], SQL type " + (sqlTypeToUse == SqlTypeValue.TYPE_UNKNOWN ? "unknown" : Integer.toString(sqlTypeToUse)));
		}
		//判断没进
		if (inValueToUse == null) {
			setNull(ps, paramIndex, sqlTypeToUse, typeNameToUse);
		}
		else {
			//设置值方法
			setValue(ps, paramIndex, sqlTypeToUse, typeNameToUse, scale, inValueToUse);
		}
	}

8.3 query功能的实现

	类JdbcTemplate：
	@Override
	public <T> List<T> query(String sql, RowMapper<T> rowMapper) throws DataAccessException {
		return query(sql, new RowMapperResultSetExtractor<T>(rowMapper));
	}

	类JdbcTemplate：
	@Override
	public <T> T query(final String sql, final ResultSetExtractor<T> rse) throws DataAccessException {
		Assert.notNull(sql, "SQL must not be null");
		Assert.notNull(rse, "ResultSetExtractor must not be null");
		if (logger.isDebugEnabled()) {
			logger.debug("Executing SQL query [" + sql + "]");
		}
		class QueryStatementCallback implements StatementCallback<T>, SqlProvider {
			@Override
			public T doInStatement(Statement stmt) throws SQLException {
				ResultSet rs = null;
				try {
					//调用连接池方法进行查询，返回resultSet
					rs = stmt.executeQuery(sql);
					ResultSet rsToUse = rs;
					//判断没进
					if (nativeJdbcExtractor != null) {
						rsToUse = nativeJdbcExtractor.getNativeResultSet(rs);
					}
					return rse.extractData(rsToUse);
				}
				finally {
					JdbcUtils.closeResultSet(rs);
				}
			}
			@Override
			public String getSql() {
				return sql;
			}
		}
		//execute方法与前面update方法的一样
		return execute(new QueryStatementCallback());
	}	

	类RowMapperResultSetExtractor：
	@Override
	public List<T> extractData(ResultSet rs) throws SQLException {
		List<T> results = (this.rowsExpected > 0 ? new ArrayList<T>(this.rowsExpected) : new ArrayList<T>());
		int rowNum = 0;
		while (rs.next()) {
			//使用rowMapper对结果集进行遍历
			//mapRow自己写的封装参数的方法
			results.add(this.rowMapper.mapRow(rs, rowNum++));
		}
		return results;
	}	

8.4 queryForObject

	类JdbcTemplate：
	@Override
	public <T> T queryForObject(String sql, Class<T> requiredType) throws DataAccessException {
		return queryForObject(sql, getSingleColumnRowMapper(requiredType));
	}
	
	类JdbcTemplate：
	@Override
	public <T> T queryForObject(String sql, RowMapper<T> rowMapper) throws DataAccessException {
		List<T> results = query(sql, rowMapper);
		return DataAccessUtils.requiredSingleResult(results);
	}
	
	类SingleColumnRowMapper：
	@Override
	@SuppressWarnings("unchecked")
	public T mapRow(ResultSet rs, int rowNum) throws SQLException {
		// Validate column count.
		//（验证返回结果数）
		ResultSetMetaData rsmd = rs.getMetaData();
		int nrOfColumns = rsmd.getColumnCount();
		if (nrOfColumns != 1) {
			throw new IncorrectResultSetColumnCountException(1, nrOfColumns);
		}

		// Extract column value from JDBC ResultSet.
		//（抽取第一个结果进行处理）
		//看：找到对应的类型把数据封装
		Object result = getColumnValue(rs, 1, this.requiredType);
		//测试：以下判断没进
		if (result != null && this.requiredType != null && !this.requiredType.isInstance(result)) {
			// Extracted value does not match already: try to convert it.
			//（转换到对应的类型）
			try {
				//convertValueToRequiredType方法后面有详细介绍
				return (T) convertValueToRequiredType(result, this.requiredType);
			}
			catch (IllegalArgumentException ex) {
				throw new TypeMismatchDataAccessException(
						"Type mismatch affecting row number " + rowNum + " and column type '" +
						rsmd.getColumnTypeName(1) + "': " + ex.getMessage());
			}
		}
		return (T) result;
	}

	类SingleColumnRowMapper：
	@SuppressWarnings("unchecked")
	protected Object convertValueToRequiredType(Object value, Class<?> requiredType) {
		if (String.class == requiredType) {
			return value.toString();
		}
		else if (Number.class.isAssignableFrom(requiredType)) {
			if (value instanceof Number) {
				// Convert original Number to target Number class.
				//（转换原始Number类型的实体到Number类）
				return NumberUtils.convertNumberToTargetClass(((Number) value), (Class<Number>) requiredType);
			}
			else {
				// Convert stringified value to target Number class.
				//（转换string类型的值到Number类）
				return NumberUtils.parseNumber(value.toString(),(Class<Number>) requiredType);
			}
		}
		else {
			throw new IllegalArgumentException(
					"Value [" + value + "] is of type [" + value.getClass().getName() +
					"] and cannot be converted to required type [" + requiredType.getName() + "]");
		}
	}	
	

第9章整合MyBatis

9.3 源码分析
9.3.1 sqlSessionFactory创建	

类SqlSessionFactoryBean：
  public void afterPropertiesSet() throws Exception {
    notNull(dataSource, "Property 'dataSource' is required");
    notNull(sqlSessionFactoryBuilder, "Property 'sqlSessionFactoryBuilder' is required");

    this.sqlSessionFactory = buildSqlSessionFactory();
  }

类SqlSessionFactoryBean：  
  protected SqlSessionFactory buildSqlSessionFactory() throws IOException {

    Configuration configuration;

    XMLConfigBuilder xmlConfigBuilder = null;
	//测试：configLocation：class path resource [com/dodi/spring/mybatis/justMybatis/SqlMapConfig.xml]
    //pdf:configLocation配置的处理
	if (this.configLocation != null) {
      xmlConfigBuilder = new XMLConfigBuilder(this.configLocation.getInputStream(), null, this.configurationProperties);
      configuration = xmlConfigBuilder.getConfiguration();
    } else {
      if (logger.isDebugEnabled()) {
        logger.debug("Property 'configLocation' not specified, using default MyBatis Configuration");
      }
      configuration = new Configuration();
      configuration.setVariables(this.configurationProperties);
    }

	//pdf:以下是其他的多种配置的处理
	//测试：都为null
    if (this.objectFactory != null) {
      configuration.setObjectFactory(this.objectFactory);
    }

    if (this.objectWrapperFactory != null) {
      configuration.setObjectWrapperFactory(this.objectWrapperFactory);
    }

    if (hasLength(this.typeAliasesPackage)) {
      String[] typeAliasPackageArray = tokenizeToStringArray(this.typeAliasesPackage,
          ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
      for (String packageToScan : typeAliasPackageArray) {
        configuration.getTypeAliasRegistry().registerAliases(packageToScan,
                typeAliasesSuperType == null ? Object.class : typeAliasesSuperType);
        if (logger.isDebugEnabled()) {
          logger.debug("Scanned package: '" + packageToScan + "' for aliases");
        }
      }
    }

    if (!isEmpty(this.typeAliases)) {
      for (Class<?> typeAlias : this.typeAliases) {
        configuration.getTypeAliasRegistry().registerAlias(typeAlias);
        if (logger.isDebugEnabled()) {
          logger.debug("Registered type alias: '" + typeAlias + "'");
        }
      }
    }

    if (!isEmpty(this.plugins)) {
      for (Interceptor plugin : this.plugins) {
        configuration.addInterceptor(plugin);
        if (logger.isDebugEnabled()) {
          logger.debug("Registered plugin: '" + plugin + "'");
        }
      }
    }

    if (hasLength(this.typeHandlersPackage)) {
      String[] typeHandlersPackageArray = tokenizeToStringArray(this.typeHandlersPackage,
          ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
      for (String packageToScan : typeHandlersPackageArray) {
        configuration.getTypeHandlerRegistry().register(packageToScan);
        if (logger.isDebugEnabled()) {
          logger.debug("Scanned package: '" + packageToScan + "' for type handlers");
        }
      }
    }

    if (!isEmpty(this.typeHandlers)) {
      for (TypeHandler<?> typeHandler : this.typeHandlers) {
        configuration.getTypeHandlerRegistry().register(typeHandler);
        if (logger.isDebugEnabled()) {
          logger.debug("Registered type handler: '" + typeHandler + "'");
        }
      }
    }

    if (xmlConfigBuilder != null) {
      try {
		// 看：parse方法为解析mybatis主配置文件SqlMapConfig.xml并封装起来
        xmlConfigBuilder.parse();

        if (logger.isDebugEnabled()) {
          logger.debug("Parsed configuration file: '" + this.configLocation + "'");
        }
      } catch (Exception ex) {
        throw new NestedIOException("Failed to parse config resource: " + this.configLocation, ex);
      } finally {
        ErrorContext.instance().reset();
      }
    }

    if (this.transactionFactory == null) {
      this.transactionFactory = new SpringManagedTransactionFactory();
    }

	//测试：environment：org.apache.ibatis.mapping.Environment@23025044，封装着连接池，SqlSessionFactoryBean，org.mybatis.spring.transaction.SpringManagedTransactionFactory@2190419
    Environment environment = new Environment(this.environment, this.transactionFactory, this.dataSource);
    configuration.setEnvironment(environment);

    if (this.databaseIdProvider != null) {
      try {
        configuration.setDatabaseId(this.databaseIdProvider.getDatabaseId(this.dataSource));
      } catch (SQLException e) {
        throw new NestedIOException("Failed getting a databaseId", e);
      }
    }

    if (!isEmpty(this.mapperLocations)) {
      for (Resource mapperLocation : this.mapperLocations) {
        if (mapperLocation == null) {
          continue;
        }

        try {
          XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(mapperLocation.getInputStream(),
              configuration, mapperLocation.toString(), configuration.getSqlFragments());
          xmlMapperBuilder.parse();
        } catch (Exception e) {
          throw new NestedIOException("Failed to parse mapping resource: '" + mapperLocation + "'", e);
        } finally {
          ErrorContext.instance().reset();
        }

        if (logger.isDebugEnabled()) {
          logger.debug("Parsed mapper file: '" + mapperLocation + "'");
        }
      }
    } else {
      if (logger.isDebugEnabled()) {
        logger.debug("Property 'mapperLocations' was not specified or no matching resources found");
      }
    }
	//new创建SqlSessionFactory工厂
    return this.sqlSessionFactoryBuilder.build(configuration);
  }

9.3.2 MapperFactoryBean的创建

	@Override
	public final void afterPropertiesSet() throws IllegalArgumentException, BeanInitializationException {
		// Let abstract subclasses check their configuration.
		
		//checkDaoConfig方法后面有详细介绍
		checkDaoConfig();

		// Let concrete implementations initialize themselves.
		try {
			//initDao方法后面有详细介绍			
			initDao();
		}
		catch (Exception ex) {
			throw new BeanInitializationException("Initialization of DAO failed", ex);
		}
	}

类MapperFactoryBean：	
  @Override
  protected void checkDaoConfig() {
    super.checkDaoConfig();

    notNull(this.mapperInterface, "Property 'mapperInterface' is required");

	//测试：configuration:封装着dataSource等多种信息
    Configuration configuration = getSqlSession().getConfiguration();
	//hasMapper方法判断configuration中是否包含此接口
    if (this.addToConfig && !configuration.hasMapper(this.mapperInterface)) {
      try {
		 //看：验证接口的映射文件是否存在，添加接口到一个map中，封装接口中的方法等 
        configuration.addMapper(this.mapperInterface);
      } catch (Throwable t) {
        logger.error("Error while adding the mapper '" + this.mapperInterface + "' to configuration.", t);
        throw new IllegalArgumentException(t);
      } finally {
        ErrorContext.instance().reset();
      }
    }
  }	
	
   protected void checkDaoConfig() {
    notNull(this.sqlSession, "Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required");
  }

9.3.3 MapperScannerConfigurer

类MapperScannerConfigurer：
  public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
    //测试：没进判断
	if (this.processPropertyPlaceHolders) {
	
	//processPropertyPlaceHolders方法后面有详细介绍
	//pdf：提前加载资源文件
      processPropertyPlaceHolders();
    }

    ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry);
    scanner.setAddToConfig(this.addToConfig);
    scanner.setAnnotationClass(this.annotationClass);
    scanner.setMarkerInterface(this.markerInterface);
    scanner.setSqlSessionFactory(this.sqlSessionFactory);
    scanner.setSqlSessionTemplate(this.sqlSessionTemplate);
    scanner.setSqlSessionFactoryBeanName(this.sqlSessionFactoryBeanName);
    scanner.setSqlSessionTemplateBeanName(this.sqlSessionTemplateBeanName);
    scanner.setResourceLoader(this.applicationContext);
    scanner.setBeanNameGenerator(this.nameGenerator);
	//registerFilters方法后面有详细介绍
    scanner.registerFilters();
	//scan方法后面有详细介绍
    scanner.scan(StringUtils.tokenizeToStringArray(this.basePackage, ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS));
  }

类MapperScannerConfigurer：  
  private void processPropertyPlaceHolders() {
    Map<String, PropertyResourceConfigurer> prcs = applicationContext.getBeansOfType(PropertyResourceConfigurer.class);

	//测试：判断没进
    if (!prcs.isEmpty() && applicationContext instanceof GenericApplicationContext) {
      BeanDefinition mapperScannerBean = ((GenericApplicationContext) applicationContext)
          .getBeanFactory().getBeanDefinition(beanName);

      // PropertyResourceConfigurer does not expose any methods to explicitly perform
      // property placeholder substitution. Instead, create a BeanFactory that just
      // contains this mapper scanner and post process the factory.
      DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
      factory.registerBeanDefinition(beanName, mapperScannerBean);

      for (PropertyResourceConfigurer prc : prcs.values()) {
        prc.postProcessBeanFactory(factory);
      }

      PropertyValues values = mapperScannerBean.getPropertyValues();

      this.basePackage = updatePropertyValue("basePackage", values);
      this.sqlSessionFactoryBeanName = updatePropertyValue("sqlSessionFactoryBeanName", values);
      this.sqlSessionTemplateBeanName = updatePropertyValue("sqlSessionTemplateBeanName", values);
    }
  }

类ClassPathMapperScanner：  
  public void registerFilters() {
    boolean acceptAllInterfaces = true;

    // if specified, use the given annotation and / or marker interface
	//（对于annotationClass属性的处理）
    if (this.annotationClass != null) {
      addIncludeFilter(new AnnotationTypeFilter(this.annotationClass));
      acceptAllInterfaces = false;
    }

    // override AssignableTypeFilter to ignore matches on the actual marker interface
	//（对于markerInterface属性的处理）
    if (this.markerInterface != null) {
      addIncludeFilter(new AssignableTypeFilter(this.markerInterface) {
        @Override
        protected boolean matchClassName(String className) {
          return false;
        }
      });
      acceptAllInterfaces = false;
    }
	//测试：acceptAllInterfaces:true
    if (acceptAllInterfaces) {
      // default include filter that accepts all classes
      addIncludeFilter(new TypeFilter() {
        public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
          return true;
        }
      });
    }

    // exclude package-info.java
	//（不扫描pachage-info.java文件）
    addExcludeFilter(new TypeFilter() {
      public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
        String className = metadataReader.getClassMetadata().getClassName();
        return className.endsWith("package-info");
      }
    });
  }  
  
类ClassPathBeanDefinitionScanner：  
	public int scan(String... basePackages) {
		//看：获得spring配置文件配置bean的个数
		int beanCountAtScanStart = this.registry.getBeanDefinitionCount();

		doScan(basePackages);

		// Register annotation config processors, if necessary.
		if (this.includeAnnotationConfig) {
			AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
		}

		return (this.registry.getBeanDefinitionCount() - beanCountAtScanStart);
	}  

类ClassPathMapperScanner：	
  @Override
  public Set<BeanDefinitionHolder> doScan(String... basePackages) {
	//super.doScan方法后面有详细介绍  
    Set<BeanDefinitionHolder> beanDefinitions = super.doScan(basePackages);

    if (beanDefinitions.isEmpty()) {
      logger.warn("No MyBatis mapper was found in '" + Arrays.toString(basePackages) + "' package. Please check your configuration.");
    } else {
		//以下方法基本没进
      for (BeanDefinitionHolder holder : beanDefinitions) {
        GenericBeanDefinition definition = (GenericBeanDefinition) holder.getBeanDefinition();

        if (logger.isDebugEnabled()) {
          logger.debug("Creating MapperFactoryBean with name '" + holder.getBeanName() 
              + "' and '" + definition.getBeanClassName() + "' mapperInterface");
        }

        // the mapper interface is the original class of the bean
        // but, the actual class of the bean is MapperFactoryBean
        definition.getPropertyValues().add("mapperInterface", definition.getBeanClassName());
        definition.setBeanClass(MapperFactoryBean.class);

        definition.getPropertyValues().add("addToConfig", this.addToConfig);

        boolean explicitFactoryUsed = false;
        if (StringUtils.hasText(this.sqlSessionFactoryBeanName)) {
          definition.getPropertyValues().add("sqlSessionFactory", new RuntimeBeanReference(this.sqlSessionFactoryBeanName));
          explicitFactoryUsed = true;
        } else if (this.sqlSessionFactory != null) {
          definition.getPropertyValues().add("sqlSessionFactory", this.sqlSessionFactory);
          explicitFactoryUsed = true;
        }

        if (StringUtils.hasText(this.sqlSessionTemplateBeanName)) {
          if (explicitFactoryUsed) {
            logger.warn("Cannot use both: sqlSessionTemplate and sqlSessionFactory together. sqlSessionFactory is ignored.");
          }
          definition.getPropertyValues().add("sqlSessionTemplate", new RuntimeBeanReference(this.sqlSessionTemplateBeanName));
          explicitFactoryUsed = true;
        } else if (this.sqlSessionTemplate != null) {
          if (explicitFactoryUsed) {
            logger.warn("Cannot use both: sqlSessionTemplate and sqlSessionFactory together. sqlSessionFactory is ignored.");
          }
          definition.getPropertyValues().add("sqlSessionTemplate", this.sqlSessionTemplate);
          explicitFactoryUsed = true;
        }

        if (!explicitFactoryUsed) {
          if (logger.isDebugEnabled()) {
            logger.debug("Enabling autowire by type for MapperFactoryBean with name '" + holder.getBeanName() + "'.");
          }
          definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
        }
      }
    }

    return beanDefinitions;
  }	

	类ClassPathBeanDefinitionScanner：
	protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
		Assert.notEmpty(basePackages, "At least one base package must be specified");
		Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<BeanDefinitionHolder>();
		for (String basePackage : basePackages) {
			//（扫描basePackage路径下java文件）
			//findCandidateComponents方法后面有详细介绍
			Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
			for (BeanDefinition candidate : candidates) {
				//（解析scope属性）
				ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
				candidate.setScope(scopeMetadata.getScopeName());
				//beanName：userMapper
				String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
				if (candidate instanceof AbstractBeanDefinition) {
					postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
				}
				if (candidate instanceof AnnotatedBeanDefinition) {
					//（如果是AnnotateeBeanDefinition类型的bean，需要检测下常用注解如：Primary、Lazy等）
					AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
				}
				//（检测当前bean是否已经注册）
				if (checkCandidate(beanName, candidate)) {
					BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
					//（如果当前bean是用于生成代理bean那么需要进一步处理）
					definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
					beanDefinitions.add(definitionHolder);
					//调用前面用到的方法
					registerBeanDefinition(definitionHolder, this.registry);
				}
			}
		}
		return beanDefinitions;
	}
	
类ClassPathScanningCandidateComponentProvider：	
	public Set<BeanDefinition> findCandidateComponents(String basePackage) {
		Set<BeanDefinition> candidates = new LinkedHashSet<BeanDefinition>();
		try {
			//测试：packageSearchPath：classpath*:com/dodi/spring/mybatis/springMybatisScanner/**/*.class
			//猜：扫描配置基本包以及其子包下的所有.class文件
			String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
					resolveBasePackage(basePackage) + "/" + this.resourcePattern;
			//测试：resources：[file [C:\lance\source\springSource\target\classes\com\dodi\spring\mybatis\springMybatisScanner\User.class], file [C:\lance\source\springSource\target\classes\com\dodi\spring\mybatis\springMybatisScanner\UserMapper.class], file [C:\lance\source\springSource\target\classes\com\dodi\spring\mybatis\springMybatisScanner\UserServiceTest.class]]		
			//猜：获得基本包下的所有类的绝对路径
			Resource[] resources = this.resourcePatternResolver.getResources(packageSearchPath);
			boolean traceEnabled = logger.isTraceEnabled();
			boolean debugEnabled = logger.isDebugEnabled();
			for (Resource resource : resources) {
				if (traceEnabled) {
					logger.trace("Scanning " + resource);
				}
				if (resource.isReadable()) {
					try {
						MetadataReader metadataReader = this.metadataReaderFactory.getMetadataReader(resource);
						//isCandidateComponent方法后面有详细介绍
						//pdf：过滤我们配置需要扫描的文件
						if (isCandidateComponent(metadataReader)) {
							ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
							sbd.setResource(resource);
							sbd.setSource(resource);
							//看：是接口文件才扫描
							if (isCandidateComponent(sbd)) {
								if (debugEnabled) {
									logger.debug("Identified candidate component class: " + resource);
								}
								candidates.add(sbd);
							}
							else {
								if (debugEnabled) {
									logger.debug("Ignored because not a concrete top-level class: " + resource);
								}
							}
						}
						else {
							if (traceEnabled) {
								logger.trace("Ignored because not matching any filter: " + resource);
							}
						}
					}
					catch (Throwable ex) {
						throw new BeanDefinitionStoreException(
								"Failed to read candidate component class: " + resource, ex);
					}
				}
				else {
					if (traceEnabled) {
						logger.trace("Ignored because not readable: " + resource);
					}
				}
			}
		}
		catch (IOException ex) {
			throw new BeanDefinitionStoreException("I/O failure during classpath scanning", ex);
		}
		return candidates;
	}	

类ClassPathScanningCandidateComponentProvider：	
	protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {
		//猜：配置不扫描的文件进这里判断
		for (TypeFilter tf : this.excludeFilters) {
			if (tf.match(metadataReader, this.metadataReaderFactory)) {
				return false;
			}
		}
		//猜：配置扫描的文件进这里判断
		for (TypeFilter tf : this.includeFilters) {
			if (tf.match(metadataReader, this.metadataReaderFactory)) {
				return isConditionMatch(metadataReader);
			}
		}
		return false;
	}
	
  
	
第11章 Springmvc


11.2.2 Spring中ContextLoaderListener

	类ContextLoaderListener：
	public void contextInitialized(ServletContextEvent event) {
		initWebApplicationContext(event.getServletContext());
	}
	
	类ContextLoader：
	public WebApplicationContext initWebApplicationContext(ServletContext servletContext) {
		//（web.xml中存在多次ContextLoader定义）
		if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null) {
			throw new IllegalStateException(
					"Cannot initialize context because there is already a root application context present - " +
					"check whether you have multiple ContextLoader* definitions in your web.xml!");
		}

		Log logger = LogFactory.getLog(ContextLoader.class);
		servletContext.log("Initializing Spring root WebApplicationContext");
		if (logger.isInfoEnabled()) {
			logger.info("Root WebApplicationContext: initialization started");
		}
		long startTime = System.currentTimeMillis();

		try {
			// Store context in local instance variable, to guarantee that
			// it is available on ServletContext shutdown.
			if (this.context == null) {
				//（初始化context）
				//createWebApplicationContext后面有详细介绍
				this.context = createWebApplicationContext(servletContext);
			}
			if (this.context instanceof ConfigurableWebApplicationContext) {
				ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) this.context;
				if (!cwac.isActive()) {
					// The context has not yet been refreshed -> provide services such as
					// setting the parent context, setting the application context id, etc
					if (cwac.getParent() == null) {
						// The context instance was injected without an explicit parent ->
						// determine parent for root web application context, if any.
						//测试：parent:null
						ApplicationContext parent = loadParentContext(servletContext);
						cwac.setParent(parent);
					}
					//cwac:Root WebApplicationContext: startup date [Thu Jan 01 08:00:00 CST 1970]; root of context hierarchy
					//读取spring配置文件初始化配置的类
					configureAndRefreshWebApplicationContext(cwac, servletContext);
				}
			}
			//（记录在servletContext中）
			servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);

			ClassLoader ccl = Thread.currentThread().getContextClassLoader();
			if (ccl == ContextLoader.class.getClassLoader()) {
				currentContext = this.context;
			}
			else if (ccl != null) {
				currentContextPerThread.put(ccl, this.context);
			}

			if (logger.isDebugEnabled()) {
				logger.debug("Published root WebApplicationContext as ServletContext attribute with name [" +
						WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE + "]");
			}
			if (logger.isInfoEnabled()) {
				long elapsedTime = System.currentTimeMillis() - startTime;
				logger.info("Root WebApplicationContext: initialization completed in " + elapsedTime + " ms");
			}

			return this.context;
		}
		catch (RuntimeException ex) {
			logger.error("Context initialization failed", ex);
			servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ex);
			throw ex;
		}
		catch (Error err) {
			logger.error("Context initialization failed", err);
			servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, err);
			throw err;
		}
	}
	
	类ContextLoader：
	protected WebApplicationContext createWebApplicationContext(ServletContext sc) {
		//determineContextClass方法后面有详细介绍
		//测试：contextClass:class org.springframework.web.context.support.XmlWebApplicationContext
		Class<?> contextClass = determineContextClass(sc);
		if (!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass)) {
			throw new ApplicationContextException("Custom context class [" + contextClass.getName() +
					"] is not of type [" + ConfigurableWebApplicationContext.class.getName() + "]");
		}
		//猜：通过反射实例化类
		return (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);
	}	
	
	类ContextLoader：
	protected Class<?> determineContextClass(ServletContext servletContext) {
		
		//测试：contextClassName:null
		String contextClassName = servletContext.getInitParameter(CONTEXT_CLASS_PARAM);
		if (contextClassName != null) {
			try {
				return ClassUtils.forName(contextClassName, ClassUtils.getDefaultClassLoader());
			}
			catch (ClassNotFoundException ex) {
				throw new ApplicationContextException(
						"Failed to load custom context class [" + contextClassName + "]", ex);
			}
		}
		else {
			//测试：contextClassName：org.springframework.web.context.support.XmlWebApplicationContext
			//猜：从ContextLoader.properties文件中读取配置
			contextClassName = defaultStrategies.getProperty(WebApplicationContext.class.getName());
			try {
				//猜：通过反射创建字节码文件
				return ClassUtils.forName(contextClassName, ContextLoader.class.getClassLoader());
			}
			catch (ClassNotFoundException ex) {
				throw new ApplicationContextException(
						"Failed to load default context class [" + contextClassName + "]", ex);
			}
		}
	}
	类ContextLoader的静态代码块：
	static {
		// Load default strategy implementations from properties file.
		// This is currently strictly internal and not meant to be customized
		// by application developers.
		try {
			ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, ContextLoader.class);
			defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
		}
		catch (IOException ex) {
			throw new IllegalStateException("Could not load 'ContextLoader.properties': " + ex.getMessage());
		}
	}
	

11.3.2 DispatcherServlet的初始化


	类HttpServletBean：
	@Override
	public final void init() throws ServletException {
		if (logger.isDebugEnabled()) {
			logger.debug("Initializing servlet '" + getServletName() + "'");
		}

		// Set bean properties from init parameters.
		try {
			//（解析init-param并封装只pvs中）
			//看：前端控制器的init-param
			//ServletConfigPropertyValues类后面有详细介绍
			//（1）
			PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties);
			//（将当前的这个Servlet类转化为一个BeanWrapper,从而能够以Spring的方式来对init-param的值进行注入）
			//（2）
			BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
			ResourceLoader resourceLoader = new ServletContextResourceLoader(getServletContext());
			//（注册自定义属性编辑器，一旦遇到Resource类型的属性将会使用ResourceEditor进行解析）
			//（3）
			bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, getEnvironment()));
			//（空实现，留给子类覆盖）
			//（4）
			initBeanWrapper(bw);
			bw.setPropertyValues(pvs, true);
		}
		catch (BeansException ex) {
			logger.error("Failed to set bean properties on servlet '" + getServletName() + "'", ex);
			throw ex;
		}

		// Let subclasses do whatever initialization they like.
		//（留给子类拓展）
		//（5）
		initServletBean();

		if (logger.isDebugEnabled()) {
			logger.debug("Servlet '" + getServletName() + "' configured successfully");
		}
	}
	类ServletConfigPropertyValues：
	public ServletConfigPropertyValues(ServletConfig config, Set<String> requiredProperties)
			throws ServletException {

			//pdf:用户可以通过requiredProperties参数的初始化强制验证某些属性的必要性
			Set<String> missingProps = (requiredProperties != null && !requiredProperties.isEmpty()) ?
					new HashSet<String>(requiredProperties) : null;

			Enumeration<String> en = config.getInitParameterNames();
			while (en.hasMoreElements()) {
				String property = en.nextElement();
				Object value = config.getInitParameter(property);
				addPropertyValue(new PropertyValue(property, value));
				if (missingProps != null) {
					missingProps.remove(property);
				}
			}

			// Fail if we are still missing properties.
			//pdf:指定验证的属性没有初始值，抛出异常
			if (missingProps != null && missingProps.size() > 0) {
				throw new ServletException(
					"Initialization from ServletConfig for servlet '" + config.getServletName() +
					"' failed; the following required properties were missing: " +
					StringUtils.collectionToDelimitedString(missingProps, ", "));
			}
		}

	类FrameworkServlet：
	@Override
	protected final void initServletBean() throws ServletException {
		getServletContext().log("Initializing Spring FrameworkServlet '" + getServletName() + "'");
		if (this.logger.isInfoEnabled()) {
			this.logger.info("FrameworkServlet '" + getServletName() + "': initialization started");
		}
		long startTime = System.currentTimeMillis();

		try {
			//initWebApplicationContext方法后面有详细介绍
			this.webApplicationContext = initWebApplicationContext();
			//（设计为子类覆盖）
			initFrameworkServlet();
		}
		catch (ServletException ex) {
			this.logger.error("Context initialization failed", ex);
			throw ex;
		}
		catch (RuntimeException ex) {
			this.logger.error("Context initialization failed", ex);
			throw ex;
		}

		if (this.logger.isInfoEnabled()) {
			//pdf:统计初始化执行时间
			long elapsedTime = System.currentTimeMillis() - startTime;
			this.logger.info("FrameworkServlet '" + getServletName() + "': initialization completed in " +
					elapsedTime + " ms");
		}
	}
	类FrameworkServlet：
	protected WebApplicationContext initWebApplicationContext() {
		WebApplicationContext rootContext =
				WebApplicationContextUtils.getWebApplicationContext(getServletContext());
		WebApplicationContext wac = null;
		//（1）
		//测试：this.webApplicationContext:null
		if (this.webApplicationContext != null) {
			// A context instance was injected at construction time -> use it
			//（context实例在构造函数中被注入）
			wac = this.webApplicationContext;
			if (wac instanceof ConfigurableWebApplicationContext) {
				ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) wac;
				if (!cwac.isActive()) {
					// The context has not yet been refreshed -> provide services such as
					// setting the parent context, setting the application context id, etc
					if (cwac.getParent() == null) {
						// The context instance was injected without an explicit parent -> set
						// the root application context (if any; may be null) as the parent
						cwac.setParent(rootContext);
					}
					//（刷新上下文环境）
					//configureAndRefreshWebApplicationContext方法后面有详细介绍
					configureAndRefreshWebApplicationContext(cwac);
				}
			}
		}
		if (wac == null) {
			// No context instance was injected at construction time -> see if one
			// has been registered in the servlet context. If one exists, it is assumed
			// that the parent context (if any) has already been set and that the
			// user has performed any initialization such as setting the context id
			//（根据contextAttribute属性加载WebApplicationContext）
			//findWebApplicationContext方法后面有详细介绍
			//（2）
			//测试：wac:null
			//猜：从缓存中查找是否有
			wac = findWebApplicationContext();
		}
		if (wac == null) {
			// No context instance is defined for this servlet -> create a local one
			//createWebApplicationContext方法后面有详细介绍
			//猜：第一次初始化，创建wac
			wac = createWebApplicationContext(rootContext);
		}
		//测试：refreshEventReceived:true，判断没进
		if (!this.refreshEventReceived) {
			// Either the context is not a ConfigurableApplicationContext with refresh
			// support or the context injected at construction time had already been
			// refreshed -> trigger initial onRefresh manually here.
			//onRefresh方法后面有详细介绍
			onRefresh(wac);
		}

		if (this.publishContext) {
			// Publish the context as a servlet context attribute.
			String attrName = getServletContextAttributeName();
			getServletContext().setAttribute(attrName, wac);
			if (this.logger.isDebugEnabled()) {
				this.logger.debug("Published WebApplicationContext of servlet '" + getServletName() +
						"' as ServletContext attribute with name [" + attrName + "]");
			}
		}
		return wac;
	}
	
	类FrameworkServlet：
	protected WebApplicationContext createWebApplicationContext(WebApplicationContext parent) {
		return createWebApplicationContext((ApplicationContext) parent);
	}
	类FrameworkServlet：
	protected WebApplicationContext createWebApplicationContext(ApplicationContext parent) {
		
		//（获取servlet的初始化参数contextClass，如果没有配置默认为XmlWebApplicationContext.class）
		Class<?> contextClass = getContextClass();
		if (this.logger.isDebugEnabled()) {
			this.logger.debug("Servlet with name '" + getServletName() +
					"' will try to create custom WebApplicationContext context of class '" +
					contextClass.getName() + "'" + ", using parent context [" + parent + "]");
		}
		//isAssignableFrom方法前面有用到过
		if (!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass)) {
			throw new ApplicationContextException(
					"Fatal initialization error in servlet with name '" + getServletName() +
					"': custom WebApplicationContext class [" + contextClass.getName() +
					"] is not of type ConfigurableWebApplicationContext");
		}
		//（通过反射方式实例化contextClass）
		ConfigurableWebApplicationContext wac =
				(ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);

		wac.setEnvironment(getEnvironment());
		//（parent为在ContextLoaderListener中创建的实例）
		//（在ContextLoaderListener加载的时候初始化的WebApplicationContext类型实例）
		wac.setParent(parent);
		//（获取contextConfigLocation属性，配置servlet初始化参数中）
		wac.setConfigLocation(getContextConfigLocation());
		//（初始化Spring环境包括加载配置文件等）
		configureAndRefreshWebApplicationContext(wac);

		return wac;
	}
	类FrameworkServlet：
	protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac) {
		if (ObjectUtils.identityToString(wac).equals(wac.getId())) {
			// The application context id is still set to its original default value
			// -> assign a more useful id based on available information
			if (this.contextId != null) {
				wac.setId(this.contextId);
			}
			else {
				// Generate default id...
				//pdf:ContextLoaderListener加载时会创建WebApplicationContext实例，并将实例以WebApplicationContext.class.getName()+".ROOT"为key放入到ServletContext中
				wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX +
						ObjectUtils.getDisplayString(getServletContext().getContextPath()) + "/" + getServletName());
			}
		}

		wac.setServletContext(getServletContext());
		wac.setServletConfig(getServletConfig());
		wac.setNamespace(getNamespace());
		wac.addApplicationListener(new SourceFilteringListener(wac, new ContextRefreshListener()));

		// The wac environment's #initPropertySources will be called in any case when the context
		// is refreshed; do it eagerly here to ensure servlet property sources are in place for
		// use in any post-processing or initialization that occurs below prior to #refresh
		ConfigurableEnvironment env = wac.getEnvironment();
		if (env instanceof ConfigurableWebEnvironment) {
			((ConfigurableWebEnvironment) env).initPropertySources(getServletContext(), getServletConfig());
		}
		
		//猜：postProcessWebApplicationContext留给子类覆盖
		postProcessWebApplicationContext(wac);
		//看：基本没做什么，第一次都为空
		applyInitializers(wac);
		//（加载配置文件及整合parent到wac）
		wac.refresh();
	}
	
	类DispatcherServlet：
	@Override
	protected void onRefresh(ApplicationContext context) {
		initStrategies(context);
	}
	类DispatcherServlet：（没测）
	protected void initStrategies(ApplicationContext context) {
		//（初始化MultipartResolver）
		initMultipartResolver(context);
		//（初始化LocaleResolver）
		initLocaleResolver(context);
		//（初始化ThemeResolver）
		initThemeResolver(context);
		//（初始化HandlerMappings）
		initHandlerMappings(context);
		//（初始化HandlerAdapters）
		initHandlerAdapters(context);
		//（初始化HandlerExceptionResolvers）
		initHandlerExceptionResolvers(context);
		//（初始化RequestToViewNameTranslator）
		initRequestToViewNameTranslator(context);
		//（初始化ViewResolvers）
		initViewResolvers(context);
		//（初始化FlashMapManager）
		initFlashMapManager(context);
	}
	类DispatcherServlet：（没测）
	private void initMultipartResolver(ApplicationContext context) {
		try {
			this.multipartResolver = context.getBean(MULTIPART_RESOLVER_BEAN_NAME, MultipartResolver.class);
			if (logger.isDebugEnabled()) {
				logger.debug("Using MultipartResolver [" + this.multipartResolver + "]");
			}
		}
		catch (NoSuchBeanDefinitionException ex) {
			// Default is no multipart resolver.
			this.multipartResolver = null;
			if (logger.isDebugEnabled()) {
				logger.debug("Unable to locate MultipartResolver with name '" + MULTIPART_RESOLVER_BEAN_NAME +
						"': no multipart request handling provided");
			}
		}
	}
	类DispatcherServlet：（没测）
	private void initLocaleResolver(ApplicationContext context) {
		try {
			this.localeResolver = context.getBean(LOCALE_RESOLVER_BEAN_NAME, LocaleResolver.class);
			if (logger.isDebugEnabled()) {
				logger.debug("Using LocaleResolver [" + this.localeResolver + "]");
			}
		}
		catch (NoSuchBeanDefinitionException ex) {
			// We need to use the default.
			this.localeResolver = getDefaultStrategy(context, LocaleResolver.class);
			if (logger.isDebugEnabled()) {
				logger.debug("Unable to locate LocaleResolver with name '" + LOCALE_RESOLVER_BEAN_NAME +
						"': using default [" + this.localeResolver + "]");
			}
		}
	}
	类DispatcherServlet：（没测）	
	private void initThemeResolver(ApplicationContext context) {
		try {
			this.themeResolver = context.getBean(THEME_RESOLVER_BEAN_NAME, ThemeResolver.class);
			if (logger.isDebugEnabled()) {
				logger.debug("Using ThemeResolver [" + this.themeResolver + "]");
			}
		}
		catch (NoSuchBeanDefinitionException ex) {
			// We need to use the default.
			this.themeResolver = getDefaultStrategy(context, ThemeResolver.class);
			if (logger.isDebugEnabled()) {
				logger.debug(
						"Unable to locate ThemeResolver with name '" + THEME_RESOLVER_BEAN_NAME + "': using default [" +
								this.themeResolver + "]");
			}
		}
	}
	类DispatcherServlet：（没测）	
	private void initHandlerMappings(ApplicationContext context) {
		this.handlerMappings = null;

		if (this.detectAllHandlerMappings) {
			// Find all HandlerMappings in the ApplicationContext, including ancestor contexts.
			Map<String, HandlerMapping> matchingBeans =
					BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);
			if (!matchingBeans.isEmpty()) {
				this.handlerMappings = new ArrayList<HandlerMapping>(matchingBeans.values());
				// We keep HandlerMappings in sorted order.
				AnnotationAwareOrderComparator.sort(this.handlerMappings);
			}
		}
		else {
			try {
				HandlerMapping hm = context.getBean(HANDLER_MAPPING_BEAN_NAME, HandlerMapping.class);
				this.handlerMappings = Collections.singletonList(hm);
			}
			catch (NoSuchBeanDefinitionException ex) {
				// Ignore, we'll add a default HandlerMapping later.
			}
		}

		// Ensure we have at least one HandlerMapping, by registering
		// a default HandlerMapping if no other mappings are found.
		if (this.handlerMappings == null) {
			this.handlerMappings = getDefaultStrategies(context, HandlerMapping.class);
			if (logger.isDebugEnabled()) {
				logger.debug("No HandlerMappings found in servlet '" + getServletName() + "': using default");
			}
		}
	}
	类DispatcherServlet：（没测）
	private void initHandlerAdapters(ApplicationContext context) {
		this.handlerAdapters = null;

		if (this.detectAllHandlerAdapters) {
			// Find all HandlerAdapters in the ApplicationContext, including ancestor contexts.
			Map<String, HandlerAdapter> matchingBeans =
					BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerAdapter.class, true, false);
			if (!matchingBeans.isEmpty()) {
				this.handlerAdapters = new ArrayList<HandlerAdapter>(matchingBeans.values());
				// We keep HandlerAdapters in sorted order.
				AnnotationAwareOrderComparator.sort(this.handlerAdapters);
			}
		}
		else {
			try {
				HandlerAdapter ha = context.getBean(HANDLER_ADAPTER_BEAN_NAME, HandlerAdapter.class);
				this.handlerAdapters = Collections.singletonList(ha);
			}
			catch (NoSuchBeanDefinitionException ex) {
				// Ignore, we'll add a default HandlerAdapter later.
			}
		}

		// Ensure we have at least some HandlerAdapters, by registering
		// default HandlerAdapters if no other adapters are found.
		if (this.handlerAdapters == null) {
			//getDefaultStrategies方法后面有详细介绍
			this.handlerAdapters = getDefaultStrategies(context, HandlerAdapter.class);
			if (logger.isDebugEnabled()) {
				logger.debug("No HandlerAdapters found in servlet '" + getServletName() + "': using default");
			}
		}
	}
	类DispatcherServlet：（没测）	
	@SuppressWarnings("unchecked")
	protected <T> List<T> getDefaultStrategies(ApplicationContext context, Class<T> strategyInterface) {
		String key = strategyInterface.getName();
		String value = defaultStrategies.getProperty(key);
		if (value != null) {
			String[] classNames = StringUtils.commaDelimitedListToStringArray(value);
			List<T> strategies = new ArrayList<T>(classNames.length);
			for (String className : classNames) {
				try {
					Class<?> clazz = ClassUtils.forName(className, DispatcherServlet.class.getClassLoader());
					Object strategy = createDefaultStrategy(context, clazz);
					strategies.add((T) strategy);
				}
				catch (ClassNotFoundException ex) {
					throw new BeanInitializationException(
							"Could not find DispatcherServlet's default strategy class [" + className +
									"] for interface [" + key + "]", ex);
				}
				catch (LinkageError err) {
					throw new BeanInitializationException(
							"Error loading DispatcherServlet's default strategy class [" + className +
									"] for interface [" + key + "]: problem with class file or dependent class", err);
				}
			}
			return strategies;
		}
		else {
			return new LinkedList<T>();
		}
	}
	类DispatcherServlet：（没测）
	static {
		// Load default strategy implementations from properties file.
		// This is currently strictly internal and not meant to be customized
		// by application developers.
		try {
			ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, DispatcherServlet.class);
			defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
		}
		catch (IOException ex) {
			throw new IllegalStateException("Could not load 'DispatcherServlet.properties': " + ex.getMessage());
		}
	}
	类DispatcherServlet：（没测）	
	private void initHandlerExceptionResolvers(ApplicationContext context) {
		this.handlerExceptionResolvers = null;

		if (this.detectAllHandlerExceptionResolvers) {
			// Find all HandlerExceptionResolvers in the ApplicationContext, including ancestor contexts.
			Map<String, HandlerExceptionResolver> matchingBeans = BeanFactoryUtils
					.beansOfTypeIncludingAncestors(context, HandlerExceptionResolver.class, true, false);
			if (!matchingBeans.isEmpty()) {
				this.handlerExceptionResolvers = new ArrayList<HandlerExceptionResolver>(matchingBeans.values());
				// We keep HandlerExceptionResolvers in sorted order.
				AnnotationAwareOrderComparator.sort(this.handlerExceptionResolvers);
			}
		}
		else {
			try {
				HandlerExceptionResolver her =
						context.getBean(HANDLER_EXCEPTION_RESOLVER_BEAN_NAME, HandlerExceptionResolver.class);
				this.handlerExceptionResolvers = Collections.singletonList(her);
			}
			catch (NoSuchBeanDefinitionException ex) {
				// Ignore, no HandlerExceptionResolver is fine too.
			}
		}

		// Ensure we have at least some HandlerExceptionResolvers, by registering
		// default HandlerExceptionResolvers if no other resolvers are found.
		if (this.handlerExceptionResolvers == null) {
			this.handlerExceptionResolvers = getDefaultStrategies(context, HandlerExceptionResolver.class);
			if (logger.isDebugEnabled()) {
				logger.debug("No HandlerExceptionResolvers found in servlet '" + getServletName() + "': using default");
			}
		}
	}
	类DispatcherServlet：（没测）
	private void initRequestToViewNameTranslator(ApplicationContext context) {
		try {
			this.viewNameTranslator =
					context.getBean(REQUEST_TO_VIEW_NAME_TRANSLATOR_BEAN_NAME, RequestToViewNameTranslator.class);
			if (logger.isDebugEnabled()) {
				logger.debug("Using RequestToViewNameTranslator [" + this.viewNameTranslator + "]");
			}
		}
		catch (NoSuchBeanDefinitionException ex) {
			// We need to use the default.
			this.viewNameTranslator = getDefaultStrategy(context, RequestToViewNameTranslator.class);
			if (logger.isDebugEnabled()) {
				logger.debug("Unable to locate RequestToViewNameTranslator with name '" +
						REQUEST_TO_VIEW_NAME_TRANSLATOR_BEAN_NAME + "': using default [" + this.viewNameTranslator +
						"]");
			}
		}
	}
	类DispatcherServlet：（没测）
	private void initViewResolvers(ApplicationContext context) {
		this.viewResolvers = null;

		if (this.detectAllViewResolvers) {
			// Find all ViewResolvers in the ApplicationContext, including ancestor contexts.
			Map<String, ViewResolver> matchingBeans =
					BeanFactoryUtils.beansOfTypeIncludingAncestors(context, ViewResolver.class, true, false);
			if (!matchingBeans.isEmpty()) {
				this.viewResolvers = new ArrayList<ViewResolver>(matchingBeans.values());
				// We keep ViewResolvers in sorted order.
				AnnotationAwareOrderComparator.sort(this.viewResolvers);
			}
		}
		else {
			try {
				ViewResolver vr = context.getBean(VIEW_RESOLVER_BEAN_NAME, ViewResolver.class);
				this.viewResolvers = Collections.singletonList(vr);
			}
			catch (NoSuchBeanDefinitionException ex) {
				// Ignore, we'll add a default ViewResolver later.
			}
		}

		// Ensure we have at least one ViewResolver, by registering
		// a default ViewResolver if no other resolvers are found.
		if (this.viewResolvers == null) {
			this.viewResolvers = getDefaultStrategies(context, ViewResolver.class);
			if (logger.isDebugEnabled()) {
				logger.debug("No ViewResolvers found in servlet '" + getServletName() + "': using default");
			}
		}
	}	
	类DispatcherServlet：（没测）	
	private void initFlashMapManager(ApplicationContext context) {
		try {
			this.flashMapManager =
					context.getBean(FLASH_MAP_MANAGER_BEAN_NAME, FlashMapManager.class);
			if (logger.isDebugEnabled()) {
				logger.debug("Using FlashMapManager [" + this.flashMapManager + "]");
			}
		}
		catch (NoSuchBeanDefinitionException ex) {
			// We need to use the default.
			this.flashMapManager = getDefaultStrategy(context, FlashMapManager.class);
			if (logger.isDebugEnabled()) {
				logger.debug("Unable to locate FlashMapManager with name '" +
						FLASH_MAP_MANAGER_BEAN_NAME + "': using default [" + this.flashMapManager + "]");
			}
		}
	}	
	
11.4 DispatcherServlet的逻辑处理	
	
	类FrameworkServlet：
	@Override
	protected final void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		processRequest(request, response);
	}

	/**
	 * Delegate POST requests to {@link #processRequest}.
	 * @see #doService
	 */
	类FrameworkServlet：
	@Override
	protected final void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		processRequest(request, response);
	}
	类FrameworkServlet：
	//https://www.2cto.com/kf/201703/605477.html
	protected final void processRequest(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		//（记录当前时间，用于计算web请求的处理时间）	
		long startTime = System.currentTimeMillis();
		Throwable failureCause = null;
		//getLocaleContext方法后面有详细介绍(localThread)
		LocaleContext previousLocaleContext = LocaleContextHolder.getLocaleContext();
		//buildLocaleContext方法后面有详细介绍(localThread)	
		//测试：localeContext：org.springframework.web.servlet.i18n.SessionLocaleResolver$1@113b239b
		LocaleContext localeContext = buildLocaleContext(request);

		//getRequestAttributes方法后面有详细介绍
		RequestAttributes previousAttributes = RequestContextHolder.getRequestAttributes();
		//buildRequestAttributes方法后面有详细介绍
		//测试：requestAttributes：org.apache.catalina.connector.RequestFacade@1c17be44
		ServletRequestAttributes requestAttributes = buildRequestAttributes(request, response, previousAttributes);

		//getAsyncManager方法后面有详细介绍
		WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
		//registerCallableInterceptor方法后面有详细介绍
		asyncManager.registerCallableInterceptor(FrameworkServlet.class.getName(), new RequestBindingInterceptor());

		//看：在ThreadLocal中set值
		//initContextHolders方法后面有详细介绍
		initContextHolders(request, localeContext, requestAttributes);

		try {
			//doService方法后面有详细介绍
			doService(request, response);
		}
		catch (ServletException ex) {
			failureCause = ex;
			throw ex;
		}
		catch (IOException ex) {
			failureCause = ex;
			throw ex;
		}
		catch (Throwable ex) {
			failureCause = ex;
			throw new NestedServletException("Request processing failed", ex);
		}

		finally {
			resetContextHolders(request, previousLocaleContext, previousAttributes);
			if (requestAttributes != null) {
				requestAttributes.requestCompleted();
			}

			if (logger.isDebugEnabled()) {
				if (failureCause != null) {
					this.logger.debug("Could not complete request", failureCause);
				}
				else {
					if (asyncManager.isConcurrentHandlingStarted()) {
						logger.debug("Leaving response open for concurrent processing");
					}
					else {
						this.logger.debug("Successfully completed request");
					}
				}
			}

			publishRequestHandledEvent(request, response, startTime, failureCause);
		}
	}

	
	private static final ThreadLocal<LocaleContext> localeContextHolder =
			new NamedThreadLocal<LocaleContext>("Locale context");
	private static final ThreadLocal<LocaleContext> inheritableLocaleContextHolder =
			new NamedInheritableThreadLocal<LocaleContext>("Locale context");
	类LocaleContextHolder：
	public static LocaleContext getLocaleContext() {
		//测试：第一次访问为localeContext:null
		LocaleContext localeContext = localeContextHolder.get();
		if (localeContext == null) {
			//测试：第一次访问为localeContext:null
			localeContext = inheritableLocaleContextHolder.get();
		}
		//测试：第一次访问为localeContext:null
		return localeContext;
	}
	类DispatcherServlet：
	@Override
	protected LocaleContext buildLocaleContext(final HttpServletRequest request) {
		if (this.localeResolver instanceof LocaleContextResolver) {
			//resolveLocaleContext方法后面有详细介绍
			return ((LocaleContextResolver) this.localeResolver).resolveLocaleContext(request);
		}
		else {
			return new LocaleContext() {
				@Override
				public Locale getLocale() {
					return localeResolver.resolveLocale(request);
				}
			};
		}
	}
	
	@Override
	public LocaleContext resolveLocaleContext(final HttpServletRequest request) {
		return new TimeZoneAwareLocaleContext() {
			@Override
			public Locale getLocale() {
				Locale locale = (Locale) WebUtils.getSessionAttribute(request, LOCALE_SESSION_ATTRIBUTE_NAME);
				if (locale == null) {
					locale = determineDefaultLocale(request);
				}
				return locale;
			}
			@Override
			public TimeZone getTimeZone() {
				TimeZone timeZone = (TimeZone) WebUtils.getSessionAttribute(request, TIME_ZONE_SESSION_ATTRIBUTE_NAME);
				if (timeZone == null) {
					timeZone = determineDefaultTimeZone(request);
				}
				return timeZone;
			}
		};
	}	
	private static final ThreadLocal<RequestAttributes> requestAttributesHolder =
			new NamedThreadLocal<RequestAttributes>("Request attributes");
	类RequestContextHolder：
	public static RequestAttributes getRequestAttributes() {
		//测试：attributes:null
		RequestAttributes attributes = requestAttributesHolder.get();
		if (attributes == null) {
			//测试：attributes:null
			attributes = inheritableRequestAttributesHolder.get();
		}
		//测试：attributes:null
		return attributes;
	}
	类FrameworkServlet：
	protected ServletRequestAttributes buildRequestAttributes(
			HttpServletRequest request, HttpServletResponse response, RequestAttributes previousAttributes) {

		if (previousAttributes == null || previousAttributes instanceof ServletRequestAttributes) {
			return new ServletRequestAttributes(request, response);
		}
		else {
			return null;  // preserve the pre-bound RequestAttributes instance
		}
	}
	类WebAsyncUtils：
	public static WebAsyncManager getAsyncManager(ServletRequest servletRequest) {
		//测试：asyncManager:null
		WebAsyncManager asyncManager = (WebAsyncManager) servletRequest.getAttribute(WEB_ASYNC_MANAGER_ATTRIBUTE);
		if (asyncManager == null) {
			asyncManager = new WebAsyncManager();
			servletRequest.setAttribute(WEB_ASYNC_MANAGER_ATTRIBUTE, asyncManager);
		}
		return asyncManager;
	}
	private final Map<Object, CallableProcessingInterceptor> callableInterceptors =
			new LinkedHashMap<Object, CallableProcessingInterceptor>();	
	类WebAsyncManager：
	public void registerCallableInterceptor(Object key, CallableProcessingInterceptor interceptor) {
		Assert.notNull(key, "Key is required");
		Assert.notNull(interceptor, "CallableProcessingInterceptor  is required");
		this.callableInterceptors.put(key, interceptor);
	}	
	类FrameworkServlet：	
	private void initContextHolders(
			HttpServletRequest request, LocaleContext localeContext, RequestAttributes requestAttributes) {

		if (localeContext != null) {
			LocaleContextHolder.setLocaleContext(localeContext, this.threadContextInheritable);
		}
		if (requestAttributes != null) {
			RequestContextHolder.setRequestAttributes(requestAttributes, this.threadContextInheritable);
		}
		if (logger.isTraceEnabled()) {
			logger.trace("Bound request context to thread: " + request);
		}
	}	
	类DispatcherServlet：
	@Override
	protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
		if (logger.isDebugEnabled()) {
			String resumed = WebAsyncUtils.getAsyncManager(request).hasConcurrentResult() ? " resumed" : "";
			logger.debug("DispatcherServlet with name '" + getServletName() + "'" + resumed +
					" processing " + request.getMethod() + " request for [" + getRequestUri(request) + "]");
		}

		// Keep a snapshot of the request attributes in case of an include,
		// to be able to restore the original attributes after the include.
		Map<String, Object> attributesSnapshot = null;
		//测试：WebUtils.isIncludeRequest(request):false
		if (WebUtils.isIncludeRequest(request)) {
			attributesSnapshot = new HashMap<String, Object>();
			Enumeration<?> attrNames = request.getAttributeNames();
			while (attrNames.hasMoreElements()) {
				String attrName = (String) attrNames.nextElement();
				if (this.cleanupAfterInclude || attrName.startsWith("org.springframework.web.servlet")) {
					attributesSnapshot.put(attrName, request.getAttribute(attrName));
				}
			}
		}

		// Make framework objects available to handlers and view objects.
		//猜：一些初始化工作
		request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, getWebApplicationContext());
		request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver);
		request.setAttribute(THEME_RESOLVER_ATTRIBUTE, this.themeResolver);
		request.setAttribute(THEME_SOURCE_ATTRIBUTE, getThemeSource());
		//测试：第一次测试时inputFlashMap:null
		FlashMap inputFlashMap = this.flashMapManager.retrieveAndUpdate(request, response);
		if (inputFlashMap != null) {
			request.setAttribute(INPUT_FLASH_MAP_ATTRIBUTE, Collections.unmodifiableMap(inputFlashMap));
		}
		request.setAttribute(OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap());
		request.setAttribute(FLASH_MAP_MANAGER_ATTRIBUTE, this.flashMapManager);

		try {
			//doDispatch方法后面有详细介绍
			doDispatch(request, response);
		}
		finally {
			if (!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {
				// Restore the original attribute snapshot, in case of an include.
				if (attributesSnapshot != null) {
					restoreAttributesAfterInclude(request, attributesSnapshot);
				}
			}
		}
	}
	类DispatcherServlet：
	protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
		HttpServletRequest processedRequest = request;
		HandlerExecutionChain mappedHandler = null;
		boolean multipartRequestParsed = false;

		WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

		try {
			ModelAndView mv = null;
			Exception dispatchException = null;

			try {
				//（如果是MultipartContent类型的request则转换request为MultipartHttpServletRequest类型的request）
				//checkMultipart方法后面有详细介绍
				processedRequest = checkMultipart(request);
				multipartRequestParsed = (processedRequest != request);

				// Determine handler for the current request.
				//（根据request信息找对应的Handler）
				//getHandler方法后面有详细介绍
				mappedHandler = getHandler(processedRequest);
				if (mappedHandler == null || mappedHandler.getHandler() == null) {
					//（如果没有找到对应的handler则通过response反馈错误信息）
					//noHandlerFound方法后面有详细介绍
					noHandlerFound(processedRequest, response);
					return;
				}

				// Determine handler adapter for the current request.
				//（根据当前的handler寻找对应的HandlerAdapter）
				//getHandlerAdapter方法后面有详细介绍
				HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

				// Process last-modified header, if supported by the handler.
				//（如果当前handler支持last-modified头处理）（没测）
				//测试：method：POST
				String method = request.getMethod();
				boolean isGet = "GET".equals(method);
				if (isGet || "HEAD".equals(method)) {
					long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
					if (logger.isDebugEnabled()) {
						logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);
					}
					if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
						return;
					}
				}
				//（拦截器的preHandler方法的调用）
				//applyPreHandle方法后面有详细介绍
				if (!mappedHandler.applyPreHandle(processedRequest, response)) {
					return;
				}

				// Actually invoke the handler.
				//（真正的激活handler并返回视图）
				mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

				//判断没进
				if (asyncManager.isConcurrentHandlingStarted()) {
					return;
				}
				//（视图名称转换应用于需要添加前缀后缀的情况）
				//看：判断没进
				applyDefaultViewName(processedRequest, mv);
				//（应用所有拦截器的postHandle方法）
				mappedHandler.applyPostHandle(processedRequest, response, mv);
			}
			catch (Exception ex) {
				dispatchException = ex;
			}
			//processDispatchResult方法后面有详细介绍
			processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
		}
		catch (Exception ex) {
			//triggerAfterCompletion方法后面有详细介绍
			//（完成处理激活触发器）
			triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
		}
		catch (Error err) {
			triggerAfterCompletionWithError(processedRequest, response, mappedHandler, err);
		}
		finally {
			if (asyncManager.isConcurrentHandlingStarted()) {
				// Instead of postHandle and afterCompletion
				if (mappedHandler != null) {
					mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
				}
			}
			else {
				// Clean up any resources used by a multipart request.
				if (multipartRequestParsed) {
					cleanupMultipart(processedRequest);
				}
			}
		}
	}

11.4.1 MultipartContent类型的request处理

	类DispatcherServlet：
	protected HttpServletRequest checkMultipart(HttpServletRequest request) throws MultipartException {
		//猜：判断是否有文件上传处理器并且请求为文件上传请求
		if (this.multipartResolver != null && this.multipartResolver.isMultipart(request)) {
			//测试：WebUtils.getNativeRequest(request, MultipartHttpServletRequest.class):null
			if (WebUtils.getNativeRequest(request, MultipartHttpServletRequest.class) != null) {
				logger.debug("Request is already a MultipartHttpServletRequest - if not in a forward, " +
						"this typically results from an additional MultipartFilter in web.xml");
			}
			//测试：request.getAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE):null
			else if (request.getAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE) instanceof MultipartException) {
				logger.debug("Multipart resolution failed for current request before - " +
						"skipping re-resolution for undisturbed error rendering");
			}
			else {
				//resolveMultipart方法后面有详细介绍
				return this.multipartResolver.resolveMultipart(request);
			}
		}
		// If not returned before: return original request.
		return request;
	}

	类CommonsMultipartResolver：
	@Override
	public MultipartHttpServletRequest resolveMultipart(final HttpServletRequest request) throws MultipartException {
		Assert.notNull(request, "Request must not be null");
		//测试：this.resolveLazily:false
		if (this.resolveLazily) {
			return new DefaultMultipartHttpServletRequest(request) {
				@Override
				protected void initializeMultipart() {
					MultipartParsingResult parsingResult = parseRequest(request);
					setMultipartFiles(parsingResult.getMultipartFiles());
					setMultipartParameters(parsingResult.getMultipartParameters());
					setMultipartParameterContentTypes(parsingResult.getMultipartParameterContentTypes());
				}
			};
		}
		else {
			//parseRequest方法后面有详细介绍
			MultipartParsingResult parsingResult = parseRequest(request);
			return new DefaultMultipartHttpServletRequest(request, parsingResult.getMultipartFiles(),
					parsingResult.getMultipartParameters(), parsingResult.getMultipartParameterContentTypes());
		}
	}

	类CommonsMultipartResolver：
	protected MultipartParsingResult parseRequest(HttpServletRequest request) throws MultipartException {
		String encoding = determineEncoding(request);
		FileUpload fileUpload = prepareFileUpload(encoding);
		try {
			List<FileItem> fileItems = ((ServletFileUpload) fileUpload).parseRequest(request);
			return parseFileItems(fileItems, encoding);
		}
		catch (FileUploadBase.SizeLimitExceededException ex) {
			throw new MaxUploadSizeExceededException(fileUpload.getSizeMax(), ex);
		}
		catch (FileUploadException ex) {
			throw new MultipartException("Could not parse multipart servlet request", ex);
		}
	}
11.4.2 根据request信息寻找对应的Handler
	类DispatcherServlet：
	protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
		for (HandlerMapping hm : this.handlerMappings) {
			if (logger.isTraceEnabled()) {
				logger.trace(
						"Testing handler map [" + hm + "] in DispatcherServlet with name '" + getServletName() + "'");
			}
			//getHandler方法后面有详细介绍
			//测试；handler：HandlerExecutionChain with handler [public java.lang.String com.dodi.spring.mvc.MvcTestController.login(java.lang.String,com.dodi.spring.mvc.User,org.springframework.web.multipart.MultipartFile) throws java.lang.Exception] and 2 interceptors
			HandlerExecutionChain handler = hm.getHandler(request);
			if (handler != null) {
				return handler;
			}
		}
		return null;
	}	
	
	类AbstractHandlerMapping：
	@Override
	public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
		//（根据request获取对应的handler）
		//测试：handler:public java.lang.String com.dodi.spring.mvc.MvcTestController.login(java.lang.String,com.dodi.spring.mvc.User,org.springframework.web.multipart.MultipartFile) throws java.lang.Exception
		Object handler = getHandlerInternal(request);
		if (handler == null) {
			//（如果没有对应request的handler则使用默认的handler）
			handler = getDefaultHandler();
		}
		//（如果也没有提供默认的handler则无法继续处理返回null）
		if (handler == null) {
			return null;
		}
		// Bean name or resolved handler?
		if (handler instanceof String) {
			String handlerName = (String) handler;
			handler = getApplicationContext().getBean(handlerName);
		}

		//getHandlerExecutionChain方法后面有详细介绍
		HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);
		if (CorsUtils.isCorsRequest(request)) {
			//测试：globalConfig:null
			CorsConfiguration globalConfig = this.corsConfigSource.getCorsConfiguration(request);
			//测试：handlerConfig:null
			CorsConfiguration handlerConfig = getCorsConfiguration(handler, request);
			//测试：config:null
			CorsConfiguration config = (globalConfig != null ? globalConfig.combine(handlerConfig) : handlerConfig);
			//getCorsHandlerExecutionChain方法不清楚
			executionChain = getCorsHandlerExecutionChain(request, executionChain, config);
		}
		//测试：executionChain：HandlerExecutionChain with handler [public java.lang.String com.dodi.spring.mvc.MvcTestController.login(java.lang.String,com.dodi.spring.mvc.User,org.springframework.web.multipart.MultipartFile) throws java.lang.Exception] and 2 interceptors
		return executionChain;
	}

	1、根据request查找对应的Handler
	类AbstractHandlerMethodMapping：
	@Override
	protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
		//（截取用于匹配的url）
		String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
		if (logger.isDebugEnabled()) {
			logger.debug("Looking up handler method for path " + lookupPath);
		}
		this.mappingRegistry.acquireReadLock();
		try {
			//lookupHandlerMethod方法不清楚
			//看：里面封装着Controller与匹配路径的方法
			//测试：handlerMethod:public java.lang.String com.dodi.spring.mvc.MvcTestController.login(java.lang.String,com.dodi.spring.mvc.User,org.springframework.web.multipart.MultipartFile) throws java.lang.Exception
			HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);
			if (logger.isDebugEnabled()) {
				if (handlerMethod != null) {
					logger.debug("Returning handler method [" + handlerMethod + "]");
				}
				else {
					logger.debug("Did not find handler method for [" + lookupPath + "]");
				}
			}
			return (handlerMethod != null ? handlerMethod.createWithResolvedBean() : null);
		}
		finally {
			this.mappingRegistry.releaseReadLock();
		}
	}

	2.加入拦截器到执行链
	类AbstractHandlerMapping：
	protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
		HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ?
				(HandlerExecutionChain) handler : new HandlerExecutionChain(handler));
		//测试：lookupPath:/login
		String lookupPath = this.urlPathHelper.getLookupPathForRequest(request);
		for (HandlerInterceptor interceptor : this.adaptedInterceptors) {
			//测试：interceptor:org.springframework.web.servlet.handler.MappedInterceptor@5f63b0a6
			if (interceptor instanceof MappedInterceptor) {
				MappedInterceptor mappedInterceptor = (MappedInterceptor) interceptor;
				if (mappedInterceptor.matches(lookupPath, this.pathMatcher)) {
					chain.addInterceptor(mappedInterceptor.getInterceptor());
				}
			}
			else {
				chain.addInterceptor(interceptor);
			}
		}
		return chain;
	}	

11.4.3 没找到对应的Handler的错误处理
	
	类DispatcherServlet：
	protected void noHandlerFound(HttpServletRequest request, HttpServletResponse response) throws Exception {
		if (pageNotFoundLogger.isWarnEnabled()) {
			pageNotFoundLogger.warn("No mapping found for HTTP request with URI [" + getRequestUri(request) +
					"] in DispatcherServlet with name '" + getServletName() + "'");
		}
		if (this.throwExceptionIfNoHandlerFound) {
			throw new NoHandlerFoundException(request.getMethod(), getRequestUri(request),
					new ServletServerHttpRequest(request).getHeaders());
		}
		else {
			response.sendError(HttpServletResponse.SC_NOT_FOUND);
		}
	}

	类DispatcherServlet：
	protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
		//pdf：遍历所有适配器来选择合适的适配器并返回它
		for (HandlerAdapter ha : this.handlerAdapters) {
			if (logger.isTraceEnabled()) {
				logger.trace("Testing handler adapter [" + ha + "]");
			}
			//supports方法后面有详细介绍
			if (ha.supports(handler)) {
				return ha;
			}
		}
		throw new ServletException("No adapter for handler [" + handler +
				"]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");
	}	
	
	类SimpleControllerHandlerAdapter：
	@Override
	public boolean supports(Object handler) {
		//pdf:SimpleControllerHandlerAdapter用于处理普通Web请求
		return (handler instanceof Controller);
	}
	
11.4.5 缓存处理（没测试）

11.4.6 HandlerInterceptor的处理（没测试）

	类HandlerExecutionChain：
	boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
		HandlerInterceptor[] interceptors = getInterceptors();
		if (!ObjectUtils.isEmpty(interceptors)) {
			for (int i = 0; i < interceptors.length; i++) {
				HandlerInterceptor interceptor = interceptors[i];
				if (!interceptor.preHandle(request, response, this.handler)) {
					triggerAfterCompletion(request, response, null);
					return false;
				}
				this.interceptorIndex = i;
			}
		}
		return true;
	}

11.4.7 逻辑处理

	类AbstractHandlerMethodAdapter：
	@Override
	public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {

		return handleInternal(request, response, (HandlerMethod) handler);
	}

	类RequestMappingHandlerAdapter：
	@Override
	protected ModelAndView handleInternal(HttpServletRequest request,
			HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {

		//checkRequest方法具体不清楚	
		checkRequest(request);

		//测试：getSessionAttributesHandler(handlerMethod).hasSessionAttributes()：false
		//getSessionAttributesHandler方法不清楚
		if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {
			applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers);
		}
		else {
			//prepareResponse方法不清楚
			prepareResponse(response);
		}

		// Execute invokeHandlerMethod in synchronized block if required.
		//测试：this.synchronizeOnSession:false（测试没进判断）
		if (this.synchronizeOnSession) {
			HttpSession session = request.getSession(false);
			if (session != null) {
				Object mutex = WebUtils.getSessionMutex(session);
				synchronized (mutex) {
					return invokeHandlerMethod(request, response, handlerMethod);
				}
			}
		}
		//invokeHandlerMethod方法后面有详细介绍（封装参数及执行Controller的逻辑方法）
		return invokeHandlerMethod(request, response, handlerMethod);
	}

	类RequestMappingHandlerAdapter：
	protected ModelAndView invokeHandlerMethod(HttpServletRequest request,
			HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {

		ServletWebRequest webRequest = new ServletWebRequest(request, response);

		//测试：第一次创建WebDataBinderFactory
		WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);
		//测试：第一次创建ModelFactory
		ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);
		//测试：创建ServletInvocableHandlerMethod，并封装值
		ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod);
		invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);
		invocableMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers);
		invocableMethod.setDataBinderFactory(binderFactory);
		invocableMethod.setParameterNameDiscoverer(this.parameterNameDiscoverer);

		//测试：创建ModelAndViewContainer，并封装值
		ModelAndViewContainer mavContainer = new ModelAndViewContainer();
		mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request));
		modelFactory.initModel(webRequest, mavContainer, invocableMethod);
		mavContainer.setIgnoreDefaultModelOnRedirect(this.ignoreDefaultModelOnRedirect);

		//测试：创建AsyncWebRequest，并封装值
		AsyncWebRequest asyncWebRequest = WebAsyncUtils.createAsyncWebRequest(request, response);
		asyncWebRequest.setTimeout(this.asyncRequestTimeout);

		//测试：asyncManager：org.springframework.web.context.request.async.WebAsyncManager@436711f
		//从servletRequest中获得WebAsyncManager
		WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
		asyncManager.setTaskExecutor(this.taskExecutor);
		asyncManager.setAsyncWebRequest(asyncWebRequest);
		asyncManager.registerCallableInterceptors(this.callableInterceptors);
		asyncManager.registerDeferredResultInterceptors(this.deferredResultInterceptors);

		//测试：asyncManager.hasConcurrentResult():false
		if (asyncManager.hasConcurrentResult()) {
			Object result = asyncManager.getConcurrentResult();
			mavContainer = (ModelAndViewContainer) asyncManager.getConcurrentResultContext()[0];
			asyncManager.clearConcurrentResult();
			if (logger.isDebugEnabled()) {
				logger.debug("Found concurrent result value [" + result + "]");
			}
			invocableMethod = invocableMethod.wrapConcurrentResult(result);
		}

		//看：封装参数与执行匹配的Controller逻辑方法
		invocableMethod.invokeAndHandle(webRequest, mavContainer);
		if (asyncManager.isConcurrentHandlingStarted()) {
			return null;
		}
		//getModelAndView后面有详细介绍
		return getModelAndView(mavContainer, modelFactory, webRequest);
	}

	类ServletInvocableHandlerMethod：
	public void invokeAndHandle(ServletWebRequest webRequest,
			ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception {

		//invokeForRequest方法后面有详细介绍   		（---重点-）	
		Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);
		//判断没进，方法不清楚
		setResponseStatus(webRequest);

		if (returnValue == null) {
			if (isRequestNotModified(webRequest) || hasResponseStatus() || mavContainer.isRequestHandled()) {
				mavContainer.setRequestHandled(true);
				return;
			}
		}
		else if (StringUtils.hasText(this.responseReason)) {
			mavContainer.setRequestHandled(true);
			return;
		}
		//设置mavContainer状态为false
		mavContainer.setRequestHandled(false);
		try {
			//handleReturnValue方法后面有详细介绍
			this.returnValueHandlers.handleReturnValue(
					returnValue, getReturnValueType(returnValue), mavContainer, webRequest);
		}
		catch (Exception ex) {
			if (logger.isTraceEnabled()) {
				logger.trace(getReturnValueHandlingErrorMessage("Error handling return value", returnValue), ex);
			}
			throw ex;
		}
	}
	
	类HandlerMethodReturnValueHandlerComposite：
	@Override
	public void handleReturnValue(Object returnValue, MethodParameter returnType,
			ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {

		//猜：根据请求选择合适的处理器
		//测试：handler：org.springframework.web.servlet.mvc.method.annotation.ViewNameMethodReturnValueHandler@273431c4
		//selectHandler方法具体不清楚
		HandlerMethodReturnValueHandler handler = selectHandler(returnValue, returnType);
		Assert.notNull(handler, "Unknown return value type [" + returnType.getParameterType().getName() + "]");
		
		handler.handleReturnValue(returnValue, returnType, mavContainer, webRequest);
	}

	类InvocableHandlerMethod：
	public Object invokeForRequest(NativeWebRequest request, ModelAndViewContainer mavContainer,
			Object... providedArgs) throws Exception {
	
		//获得并封装所有参数
		//getMethodArgumentValues方法后面有详细介绍
		Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);
		if (logger.isTraceEnabled()) {
			StringBuilder sb = new StringBuilder("Invoking [");
			sb.append(getBeanType().getSimpleName()).append(".");
			sb.append(getMethod().getName()).append("] method with arguments ");
			sb.append(Arrays.asList(args));
			logger.trace(sb.toString());
		}
		//猜：执行Controller方法
		//doInvoke方法后面有详细介绍
		//测试：returnValue:mvc
		Object returnValue = doInvoke(args);
		if (logger.isTraceEnabled()) {
			logger.trace("Method [" + getMethod().getName() + "] returned [" + returnValue + "]");
		}
		return returnValue;
	}
	
	类InvocableHandlerMethod：
	private Object[] getMethodArgumentValues(NativeWebRequest request, ModelAndViewContainer mavContainer,
			Object... providedArgs) throws Exception {

		//测试：parameters：[org.springframework.web.method.HandlerMethod$HandlerMethodParameter@4d7694d3, org.springframework.web.method.HandlerMethod$HandlerMethodParameter@4d7694d4, org.springframework.web.method.HandlerMethod$HandlerMethodParameter@4d7694d5]	
		//getMethodParameters方法具体不清楚
		//MethodParameter类中封装着页面传过来参数的名字，类型等
		MethodParameter[] parameters = getMethodParameters();
		Object[] args = new Object[parameters.length];
		for (int i = 0; i < parameters.length; i++) {
			MethodParameter parameter = parameters[i];
			//给parameter的成员变量赋值
			parameter.initParameterNameDiscovery(this.parameterNameDiscoverer);
			//设置参数的类型
			GenericTypeResolver.resolveParameterType(parameter, getBean().getClass());
			//测试：args[i]:null
			//resolveProvidedArgument方法不清楚
			//猜：resolveProvidedArgument不同参数类型有不同的处理器，获得后放到了一个map中
			args[i] = resolveProvidedArgument(parameter, providedArgs);
			if (args[i] != null) {
				continue;
			}
			//猜：判断参数是否为空
			//supportsParameter方法具体不清楚
			if (this.argumentResolvers.supportsParameter(parameter)) {
				try {
					//看：封装各参数的方法
					//resolveArgument方法后面有详细介绍
					args[i] = this.argumentResolvers.resolveArgument(
							parameter, mavContainer, request, this.dataBinderFactory);
					continue;
				}
				catch (Exception ex) {
					if (logger.isDebugEnabled()) {
						logger.debug(getArgumentResolutionErrorMessage("Error resolving argument", i), ex);
					}
					throw ex;
				}
			}
			if (args[i] == null) {
				String msg = getArgumentResolutionErrorMessage("No suitable resolver for argument", i);
				throw new IllegalStateException(msg);
			}
		}
		return args;
	}
	类HandlerMethodArgumentResolverComposite：
	@Override
	public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
			NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {

		
		//获得参数处理器
		//测试：2.pojo参数：resolver：org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor@2c0ada10
		HandlerMethodArgumentResolver resolver = getArgumentResolver(parameter);
		if (resolver == null) {
			throw new IllegalArgumentException("Unknown parameter type [" + parameter.getParameterType().getName() + "]");
		}
		//resolveArgument方法后面有详细介绍
		return resolver.resolveArgument(parameter, mavContainer, webRequest, binderFactory);
	}	

	类AbstractNamedValueMethodArgumentResolver：（1.普通参数封装）
	@Override
	public final Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
			NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {

		//获得当前参数的class类型	
		Class<?> paramType = parameter.getParameterType();
		//namedValueInfo封装着参数名字的内部类
		NamedValueInfo namedValueInfo = getNamedValueInfo(parameter);

		//resolveName方法后面有详细介绍
		//看：封装参数方法                     （--重要--）
		//1.普通参数不为null
		Object arg = resolveName(namedValueInfo.name, parameter, webRequest);
		
		if (arg == null) {
			if (namedValueInfo.defaultValue != null) {
				arg = resolveDefaultValue(namedValueInfo.defaultValue);
			}
			else if (namedValueInfo.required && !parameter.getParameterType().getName().equals("java.util.Optional")) {
				handleMissingValue(namedValueInfo.name, parameter);
			}
			arg = handleNullValue(namedValueInfo.name, arg, paramType);
		}
		else if ("".equals(arg) && namedValueInfo.defaultValue != null) {
			arg = resolveDefaultValue(namedValueInfo.defaultValue);
		}
		//测试：1.普通参数binderFactory：org.springframework.web.servlet.mvc.method.annotation.ServletRequestDataBinderFactory@8035042
		if (binderFactory != null) {
			//createBinder方法不清楚
			//看：createBinder方法只创建一个新的WebDataBinder
			WebDataBinder binder = binderFactory.createBinder(webRequest, null, namedValueInfo.name);
			try {
				//binder的convertIfNecessary方法
				arg = binder.convertIfNecessary(arg, paramType, parameter);
			}
			catch (ConversionNotSupportedException ex) {
				throw new MethodArgumentConversionNotSupportedException(arg, ex.getRequiredType(),
						namedValueInfo.name, parameter, ex.getCause());
			}
			catch (TypeMismatchException ex) {
				throw new MethodArgumentTypeMismatchException(arg, ex.getRequiredType(),
						namedValueInfo.name, parameter, ex.getCause());

			}
		}
		//handleResolvedValue方法为空方法
		handleResolvedValue(arg, namedValueInfo.name, parameter, mavContainer, webRequest);

		return arg;
	}
	
	类ModelAttributeMethodProcessor：（pojo封装）
	@Override
	public final Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
			NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
		//测试：name：user
		//猜：获得方法参数pojo对象名字
		String name = ModelFactory.getNameForParameter(parameter);
		//猜：容器中没有此对象，创建
		//createAttribute方法创建此对象
		//attribute:com.dodi.spring.mvc.User@525aaff
		Object attribute = (mavContainer.containsAttribute(name) ?
				mavContainer.getModel().get(name) : createAttribute(name, parameter, binderFactory, webRequest));
		
		//创建ExtendedServletRequestDataBinder对象并给ConversionService赋值
		WebDataBinder binder = binderFactory.createBinder(webRequest, attribute, name);
		if (binder.getTarget() != null) {
			//bindRequestParameters方法后面有详细介绍
			bindRequestParameters(binder, webRequest);
			//判断没进，方法不清楚
			validateIfApplicable(binder, parameter);
			if (binder.getBindingResult().hasErrors() && isBindExceptionRequired(binder, parameter)) {
				throw new BindException(binder.getBindingResult());
			}
		}

		// Add resolved attribute and BindingResult at the end of the model
		//猜：把属性放到mavContainer容器中
		Map<String, Object> bindingResultModel = binder.getBindingResult().getModel();
		mavContainer.removeAttributes(bindingResultModel);
		mavContainer.addAllAttributes(bindingResultModel);
		//convertIfNecessary方法不清楚
		return binder.convertIfNecessary(binder.getTarget(), parameter.getParameterType(), parameter);
	}
	
	@Override(pojo参数封装)
	protected void bindRequestParameters(WebDataBinder binder, NativeWebRequest request) {
		ServletRequest servletRequest = request.getNativeRequest(ServletRequest.class);
		ServletRequestDataBinder servletBinder = (ServletRequestDataBinder) binder;
		servletBinder.bind(servletRequest);
	}
	
	public void bind(ServletRequest request) {
		MutablePropertyValues mpvs = new ServletRequestParameterPropertyValues(request);
		MultipartRequest multipartRequest = WebUtils.getNativeRequest(request, MultipartRequest.class);
		if (multipartRequest != null) {
			bindMultipart(multipartRequest.getMultiFileMap(), mpvs);
		}
		addBindValues(mpvs, request);
		doBind(mpvs);
	}
	
	类WebDataBinder：(pojo参数封装)
	@Override
	protected void doBind(MutablePropertyValues mpvs) {
		//检查，测试判断都没进
		checkFieldDefaults(mpvs);
		//检查，测试判断都没进
		checkFieldMarkers(mpvs);
		//doBind方法后面有详细介绍
		super.doBind(mpvs);
	}
	
	类DataBinder：(pojo参数封装)
	protected void doBind(MutablePropertyValues mpvs) {
		//检查，测试判断都没进
		checkAllowedFields(mpvs);
		//检查，测试判断都没进
		checkRequiredFields(mpvs);
		
		applyPropertyValues(mpvs);
	}
	类：(pojo参数封装)
	protected void applyPropertyValues(MutablePropertyValues mpvs) {
		try {
			// Bind request parameters onto target object.
			getPropertyAccessor().setPropertyValues(mpvs, isIgnoreUnknownFields(), isIgnoreInvalidFields());
		}
		catch (PropertyBatchUpdateException ex) {
			// Use bind error processor to create FieldErrors.
			for (PropertyAccessException pae : ex.getPropertyAccessExceptions()) {
				getBindingErrorProcessor().processPropertyAccessException(pae, getInternalBindingResult());
			}
		}
	}
	类AbstractPropertyAccessor：(pojo参数封装)
	@Override
	public void setPropertyValues(PropertyValues pvs, boolean ignoreUnknown, boolean ignoreInvalid)
			throws BeansException {

		List<PropertyAccessException> propertyAccessExceptions = null;
		//测试：pvs instanceof MutablePropertyValues：true
		//测试：propertyValues:[bean property 'age', bean property 'id', bean property 'username', bean property 'uploadFile']
		//猜：从前端传过来的参数以及值
		List<PropertyValue> propertyValues = (pvs instanceof MutablePropertyValues ?
				((MutablePropertyValues) pvs).getPropertyValueList() : Arrays.asList(pvs.getPropertyValues()));
		//猜：遍历赋值
		for (PropertyValue pv : propertyValues) {
			try {
				// This method may throw any BeansException, which won't be caught
				// here, if there is a critical failure such as no matching field.
				// We can attempt to deal only with less serious exceptions.
				//setPropertyValue方法后面有详细介绍
				setPropertyValue(pv);
			}
			catch (NotWritablePropertyException ex) {
				if (!ignoreUnknown) {
					throw ex;
				}
				// Otherwise, just ignore it and continue...
			}
			catch (NullValueInNestedPathException ex) {
				if (!ignoreInvalid) {
					throw ex;
				}
				// Otherwise, just ignore it and continue...
			}
			catch (PropertyAccessException ex) {
				if (propertyAccessExceptions == null) {
					propertyAccessExceptions = new LinkedList<PropertyAccessException>();
				}
				propertyAccessExceptions.add(ex);
			}
		}

		// If we encountered individual exceptions, throw the composite exception.
		if (propertyAccessExceptions != null) {
			PropertyAccessException[] paeArray =
					propertyAccessExceptions.toArray(new PropertyAccessException[propertyAccessExceptions.size()]);
			throw new PropertyBatchUpdateException(paeArray);
		}
	}
	类AbstractNestablePropertyAccessor：(pojo参数封装)
	@Override
	public void setPropertyValue(PropertyValue pv) throws BeansException {
		PropertyTokenHolder tokens = (PropertyTokenHolder) pv.resolvedTokens;
		if (tokens == null) {
			String propertyName = pv.getName();
			AbstractNestablePropertyAccessor nestedPa;
			try {
				//测试：nestedPa：org.springframework.beans.BeanWrapperImpl: wrapping object [com.dodi.spring.mvc.User@525aaff]
				nestedPa = getPropertyAccessorForPropertyPath(propertyName);
			}
			catch (NotReadablePropertyException ex) {
				throw new NotWritablePropertyException(getRootClass(), this.nestedPath + propertyName,
						"Nested property in path '" + propertyName + "' does not exist", ex);
			}
			//测试：tokens：org.springframework.beans.AbstractNestablePropertyAccessor$PropertyTokenHolder@6a3df21c
			//看：包含当前封装参数名字（age）
			tokens = getPropertyNameTokens(getFinalPath(nestedPa, propertyName));
			if (nestedPa == this) {
				//以下代码不清楚
				pv.getOriginalPropertyValue().resolvedTokens = tokens;
			}
			
			nestedPa.setPropertyValue(tokens, pv);
		}
		else {
			setPropertyValue(tokens, pv);
		}
	}
	
	类AbstractNestablePropertyAccessor：(pojo参数封装)
	@SuppressWarnings("unchecked")
	protected void setPropertyValue(PropertyTokenHolder tokens, PropertyValue pv) throws BeansException {
		
		//看：页面传递过来的参数名字
		//测试：propertyName（actualName）：age
		String propertyName = tokens.canonicalName;
		String actualName = tokens.actualName;

		if (tokens.keys != null) {
			// Apply indexes and map keys: fetch value for all keys but the last one.
			PropertyTokenHolder getterTokens = new PropertyTokenHolder();
			getterTokens.canonicalName = tokens.canonicalName;
			getterTokens.actualName = tokens.actualName;
			getterTokens.keys = new String[tokens.keys.length - 1];
			System.arraycopy(tokens.keys, 0, getterTokens.keys, 0, tokens.keys.length - 1);
			Object propValue;
			try {
				propValue = getPropertyValue(getterTokens);
			}
			catch (NotReadablePropertyException ex) {
				throw new NotWritablePropertyException(getRootClass(), this.nestedPath + propertyName,
						"Cannot access indexed value in property referenced " +
								"in indexed property path '" + propertyName + "'", ex);
			}
			// Set value for last key.
			String key = tokens.keys[tokens.keys.length - 1];
			if (propValue == null) {
				// null map value case
				if (isAutoGrowNestedPaths()) {
					// TODO: cleanup, this is pretty hacky
					int lastKeyIndex = tokens.canonicalName.lastIndexOf('[');
					getterTokens.canonicalName = tokens.canonicalName.substring(0, lastKeyIndex);
					propValue = setDefaultValue(getterTokens);
				}
				else {
					throw new NullValueInNestedPathException(getRootClass(), this.nestedPath + propertyName,
							"Cannot access indexed value in property referenced " +
									"in indexed property path '" + propertyName + "': returned null");
				}
			}
			if (propValue.getClass().isArray()) {
				PropertyHandler ph = getLocalPropertyHandler(actualName);
				Class<?> requiredType = propValue.getClass().getComponentType();
				int arrayIndex = Integer.parseInt(key);
				Object oldValue = null;
				try {
					if (isExtractOldValueForEditor() && arrayIndex < Array.getLength(propValue)) {
						oldValue = Array.get(propValue, arrayIndex);
					}
					Object convertedValue = convertIfNecessary(propertyName, oldValue, pv.getValue(),
							requiredType, ph.nested(tokens.keys.length));
					int length = Array.getLength(propValue);
					if (arrayIndex >= length && arrayIndex < this.autoGrowCollectionLimit) {
						Class<?> componentType = propValue.getClass().getComponentType();
						Object newArray = Array.newInstance(componentType, arrayIndex + 1);
						System.arraycopy(propValue, 0, newArray, 0, length);
						setPropertyValue(actualName, newArray);
						propValue = getPropertyValue(actualName);
					}
					Array.set(propValue, arrayIndex, convertedValue);
				}
				catch (IndexOutOfBoundsException ex) {
					throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
							"Invalid array index in property path '" + propertyName + "'", ex);
				}
			}
			else if (propValue instanceof List) {
				PropertyHandler ph = getPropertyHandler(actualName);
				Class<?> requiredType = ph.getCollectionType(tokens.keys.length);
				List<Object> list = (List<Object>) propValue;
				int index = Integer.parseInt(key);
				Object oldValue = null;
				if (isExtractOldValueForEditor() && index < list.size()) {
					oldValue = list.get(index);
				}
				Object convertedValue = convertIfNecessary(propertyName, oldValue, pv.getValue(),
						requiredType, ph.nested(tokens.keys.length));
				int size = list.size();
				if (index >= size && index < this.autoGrowCollectionLimit) {
					for (int i = size; i < index; i++) {
						try {
							list.add(null);
						}
						catch (NullPointerException ex) {
							throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
									"Cannot set element with index " + index + " in List of size " +
											size + ", accessed using property path '" + propertyName +
											"': List does not support filling up gaps with null elements");
						}
					}
					list.add(convertedValue);
				}
				else {
					try {
						list.set(index, convertedValue);
					}
					catch (IndexOutOfBoundsException ex) {
						throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
								"Invalid list index in property path '" + propertyName + "'", ex);
					}
				}
			}
			else if (propValue instanceof Map) {
				PropertyHandler ph = getLocalPropertyHandler(actualName);
				Class<?> mapKeyType = ph.getMapKeyType(tokens.keys.length);
				Class<?> mapValueType = ph.getMapValueType(tokens.keys.length);
				Map<Object, Object> map = (Map<Object, Object>) propValue;
				// IMPORTANT: Do not pass full property name in here - property editors
				// must not kick in for map keys but rather only for map values.
				TypeDescriptor typeDescriptor = TypeDescriptor.valueOf(mapKeyType);
				Object convertedMapKey = convertIfNecessary(null, null, key, mapKeyType, typeDescriptor);
				Object oldValue = null;
				if (isExtractOldValueForEditor()) {
					oldValue = map.get(convertedMapKey);
				}
				// Pass full property name and old value in here, since we want full
				// conversion ability for map values.
				Object convertedMapValue = convertIfNecessary(propertyName, oldValue, pv.getValue(),
						mapValueType, ph.nested(tokens.keys.length));
				map.put(convertedMapKey, convertedMapValue);
			}
			else {
				throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
						"Property referenced in indexed property path '" + propertyName +
								"' is neither an array nor a List nor a Map; returned value was [" + propValue + "]");
			}
		}
		//测试进入这里
		else {
			//测试：ph:org.springframework.beans.BeanWrapperImpl$BeanPropertyHandler@4d04c16d
			//看：ph中包含有user对象信息
			PropertyHandler ph = getLocalPropertyHandler(actualName);
			if (ph == null || !ph.isWritable()) {
				if (pv.isOptional()) {
					if (logger.isDebugEnabled()) {
						logger.debug("Ignoring optional value for property '" + actualName +
								"' - property not found on bean class [" + getRootClass().getName() + "]");
					}
					return;
				}
				else {
					throw createNotWritablePropertyException(propertyName);
				}
			}
			Object oldValue = null;
			try {
				//看：页面传递过来的参数值
				//测试：originalValue（valueToApply）：55
				Object originalValue = pv.getValue();
				Object valueToApply = originalValue;
				if (!Boolean.FALSE.equals(pv.conversionNecessary)) {
					if (pv.isConverted()) {
						valueToApply = pv.getConvertedValue();
					}
					else {
						if (isExtractOldValueForEditor() && ph.isReadable()) {
							try {
								//测试：oldValue：null
								oldValue = ph.getValue();
							}
							catch (Exception ex) {
								if (ex instanceof PrivilegedActionException) {
									ex = ((PrivilegedActionException) ex).getException();
								}
								if (logger.isDebugEnabled()) {
									logger.debug("Could not read previous value of property '" +
											this.nestedPath + propertyName + "'", ex);
								}
							}
						}
						//看：convertForProperty方法为参数类型的转换（String-->Integer）
						valueToApply = convertForProperty(
								propertyName, oldValue, originalValue, ph.toTypeDescriptor());
					}
					pv.getOriginalPropertyValue().conversionNecessary = (valueToApply != originalValue);
				}
				//setValue方法后面有详细介绍
				ph.setValue(object, valueToApply);
			}
			catch (TypeMismatchException ex) {
				throw ex;
			}
			catch (InvocationTargetException ex) {
				PropertyChangeEvent propertyChangeEvent =
						new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue());
				if (ex.getTargetException() instanceof ClassCastException) {
					throw new TypeMismatchException(propertyChangeEvent, ph.getPropertyType(), ex.getTargetException());
				}
				else {
					Throwable cause = ex.getTargetException();
					if (cause instanceof UndeclaredThrowableException) {
						// May happen e.g. with Groovy-generated methods
						cause = cause.getCause();
					}
					throw new MethodInvocationException(propertyChangeEvent, cause);
				}
			}
			catch (Exception ex) {
				PropertyChangeEvent pce =
						new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue());
				throw new MethodInvocationException(pce, ex);
			}
		}
	}
	
	@Override
	public void setValue(final Object object, Object valueToApply) throws Exception {
			
			//测试：writeMethod：public void com.dodi.spring.mvc.User.setAge(java.lang.Integer)
			//看：获得属性的set方法
			final Method writeMethod = (this.pd instanceof GenericTypeAwarePropertyDescriptor ?
					((GenericTypeAwarePropertyDescriptor) this.pd).getWriteMethodForActualAccess() :
					this.pd.getWriteMethod());
			//测试：判断没进
			if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers()) && !writeMethod.isAccessible()) {
				if (System.getSecurityManager() != null) {
					AccessController.doPrivileged(new PrivilegedAction<Object>() {
						@Override
						public Object run() {
							writeMethod.setAccessible(true);
							return null;
						}
					});
				}
				else {
					writeMethod.setAccessible(true);
				}
			}
			final Object value = valueToApply;
			if (System.getSecurityManager() != null) {
				try {
					AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
						@Override
						public Object run() throws Exception {
							writeMethod.invoke(object, value);
							return null;
						}
					}, acc);
				}
				catch (PrivilegedActionException ex) {
					throw ex.getException();
				}
			}
			else {
				//看：执行set方法给pojo类属性赋值
				writeMethod.invoke(getWrappedInstance(), value);
			}
	}
	
	
	@Override
	public <T> T convertIfNecessary(Object value, Class<T> requiredType, MethodParameter methodParam)
			throws TypeMismatchException {

		return getTypeConverter().convertIfNecessary(value, requiredType, methodParam);
	}	
	
	protected TypeConverter getTypeConverter() {
		if (getTarget() != null) {
			return getInternalBindingResult().getPropertyAccessor();
		}
		else {
			//看：普通参数跑这里
			return getSimpleTypeConverter();
		}
	}

	@Override
	public <T> T convertIfNecessary(Object value, Class<T> requiredType, MethodParameter methodParam)
			throws TypeMismatchException {

		return doConvert(value, requiredType, methodParam, null);
	}

	private <T> T doConvert(Object value, Class<T> requiredType, MethodParameter methodParam, Field field)
			throws TypeMismatchException {
		try {
			//1.普通参数：field：null
			if (field != null) {
				return this.typeConverterDelegate.convertIfNecessary(value, requiredType, field);
			}
			else {
				return this.typeConverterDelegate.convertIfNecessary(value, requiredType, methodParam);
			}
		}
		catch (ConverterNotFoundException ex) {
			throw new ConversionNotSupportedException(value, requiredType, ex);
		}
		catch (ConversionException ex) {
			throw new TypeMismatchException(value, requiredType, ex);
		}
		catch (IllegalStateException ex) {
			throw new ConversionNotSupportedException(value, requiredType, ex);
		}
		catch (IllegalArgumentException ex) {
			throw new TypeMismatchException(value, requiredType, ex);
		}
	}	
	
	
	类RequestParamMethodArgumentResolver：
	@Override
	protected Object resolveName(String name, MethodParameter parameter, NativeWebRequest webRequest) throws Exception {
		//猜：获得当前请求
		//getNativeRequest方法不清楚
		HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class);
		//看：把servletRequest转换成MultipartHttpServletRequest
		MultipartHttpServletRequest multipartRequest =
				WebUtils.getNativeRequest(servletRequest, MultipartHttpServletRequest.class);
		Object arg;
		
		//猜：判断是否为文件上传参数
		if (MultipartFile.class == parameter.getParameterType()) {
			assertIsMultipartRequest(servletRequest);
			Assert.notNull(multipartRequest, "Expected MultipartHttpServletRequest: is a MultipartResolver configured?");
			arg = multipartRequest.getFile(name);
		}
		//猜：判断是否为文件集合上传参数
		else if (isMultipartFileCollection(parameter)) {
			assertIsMultipartRequest(servletRequest);
			Assert.notNull(multipartRequest, "Expected MultipartHttpServletRequest: is a MultipartResolver configured?");
			arg = multipartRequest.getFiles(name);
		}
		//猜：判断是否为文件数组上传参数
		else if (isMultipartFileArray(parameter)) {
			assertIsMultipartRequest(servletRequest);
			Assert.notNull(multipartRequest, "Expected MultipartHttpServletRequest: is a MultipartResolver configured?");
			List<MultipartFile> multipartFiles = multipartRequest.getFiles(name);
			arg = multipartFiles.toArray(new MultipartFile[multipartFiles.size()]);
		}
		//猜：判断是否为javax.servlet.http.Part参数
		else if ("javax.servlet.http.Part".equals(parameter.getParameterType().getName())) {
			assertIsMultipartRequest(servletRequest);
			arg = servletRequest.getPart(name);
		}
		//猜：判断是否为javax.servlet.http.Part集合参数
		else if (isPartCollection(parameter)) {
			assertIsMultipartRequest(servletRequest);
			arg = new ArrayList<Object>(servletRequest.getParts());
		}
		//猜：判断是否为javax.servlet.http.Part数组参数
		else if (isPartArray(parameter)) {
			assertIsMultipartRequest(servletRequest);
			arg = RequestPartResolver.resolvePart(servletRequest);
		}
		else {
			arg = null;
			if (multipartRequest != null) {
				//看：获得所有上传的文件MultipartFile的list，不是文件类型时为空
				List<MultipartFile> files = multipartRequest.getFiles(name);
				if (!files.isEmpty()) {
					arg = (files.size() == 1 ? files.get(0) : files);
				}
			}
			if (arg == null) {
				//看：通过当前参数名字获得当前参数的值
				String[] paramValues = webRequest.getParameterValues(name);
				if (paramValues != null) {
					arg = (paramValues.length == 1 ? paramValues[0] : paramValues);
				}
			}
		}

		return arg;
	}


	类TypeConverterDelegate：
	@SuppressWarnings("unchecked")
	public <T> T convertIfNecessary(String propertyName, Object oldValue, Object newValue,
			Class<T> requiredType, TypeDescriptor typeDescriptor) throws IllegalArgumentException {

		// Custom editor for this type?
		//测试：editor：null
		PropertyEditor editor = this.propertyEditorRegistry.findCustomEditor(requiredType, propertyName);

		ConversionFailedException conversionAttemptEx = null;

		// No custom editor but custom ConversionService specified?
		//测试：conversionService：各种基本类型
		ConversionService conversionService = this.propertyEditorRegistry.getConversionService();
		if (editor == null && conversionService != null && newValue != null && typeDescriptor != null) {
			//1.基本类型进来了
			//sourceTypeDesc：参数类型
			TypeDescriptor sourceTypeDesc = TypeDescriptor.forObject(newValue);
			//canConvert方法不清楚
			if (conversionService.canConvert(sourceTypeDesc, typeDescriptor)) {
				try {
					//convert方法封装参数
					return (T) conversionService.convert(newValue, sourceTypeDesc, typeDescriptor);
				}
				catch (ConversionFailedException ex) {
					// fallback to default conversion logic below
					conversionAttemptEx = ex;
				}
			}
		}

		Object convertedValue = newValue;

		// Value not of required type?
		if (editor != null || (requiredType != null && !ClassUtils.isAssignableValue(requiredType, convertedValue))) {
			if (requiredType != null && Collection.class.isAssignableFrom(requiredType) && convertedValue instanceof String) {
				TypeDescriptor elementType = typeDescriptor.getElementTypeDescriptor();
				if (elementType != null && Enum.class.isAssignableFrom(elementType.getType())) {
					convertedValue = StringUtils.commaDelimitedListToStringArray((String) convertedValue);
				}
			}
			if (editor == null) {
				editor = findDefaultEditor(requiredType);
			}
			convertedValue = doConvertValue(oldValue, convertedValue, requiredType, editor);
		}

		boolean standardConversion = false;

		if (requiredType != null) {
			// Try to apply some standard type conversion rules if appropriate.

			if (convertedValue != null) {
				if (Object.class == requiredType) {
					return (T) convertedValue;
				}
				else if (requiredType.isArray()) {
					// Array required -> apply appropriate conversion of elements.
					if (convertedValue instanceof String && Enum.class.isAssignableFrom(requiredType.getComponentType())) {
						convertedValue = StringUtils.commaDelimitedListToStringArray((String) convertedValue);
					}
					return (T) convertToTypedArray(convertedValue, propertyName, requiredType.getComponentType());
				}
				else if (convertedValue instanceof Collection) {
					// Convert elements to target type, if determined.
					convertedValue = convertToTypedCollection(
							(Collection<?>) convertedValue, propertyName, requiredType, typeDescriptor);
					standardConversion = true;
				}
				else if (convertedValue instanceof Map) {
					// Convert keys and values to respective target type, if determined.
					convertedValue = convertToTypedMap(
							(Map<?, ?>) convertedValue, propertyName, requiredType, typeDescriptor);
					standardConversion = true;
				}
				if (convertedValue.getClass().isArray() && Array.getLength(convertedValue) == 1) {
					convertedValue = Array.get(convertedValue, 0);
					standardConversion = true;
				}
				if (String.class == requiredType && ClassUtils.isPrimitiveOrWrapper(convertedValue.getClass())) {
					// We can stringify any primitive value...
					return (T) convertedValue.toString();
				}
				else if (convertedValue instanceof String && !requiredType.isInstance(convertedValue)) {
					if (conversionAttemptEx == null && !requiredType.isInterface() && !requiredType.isEnum()) {
						try {
							Constructor<T> strCtor = requiredType.getConstructor(String.class);
							return BeanUtils.instantiateClass(strCtor, convertedValue);
						}
						catch (NoSuchMethodException ex) {
							// proceed with field lookup
							if (logger.isTraceEnabled()) {
								logger.trace("No String constructor found on type [" + requiredType.getName() + "]", ex);
							}
						}
						catch (Exception ex) {
							if (logger.isDebugEnabled()) {
								logger.debug("Construction via String failed for type [" + requiredType.getName() + "]", ex);
							}
						}
					}
					String trimmedValue = ((String) convertedValue).trim();
					if (requiredType.isEnum() && "".equals(trimmedValue)) {
						// It's an empty enum identifier: reset the enum value to null.
						return null;
					}
					convertedValue = attemptToConvertStringToEnum(requiredType, trimmedValue, convertedValue);
					standardConversion = true;
				}
				else if (convertedValue instanceof Number && Number.class.isAssignableFrom(requiredType)) {
					convertedValue = NumberUtils.convertNumberToTargetClass(
							(Number) convertedValue, (Class<Number>) requiredType);
					standardConversion = true;
				}
			}
			else {
				// convertedValue == null
				if (javaUtilOptionalEmpty != null && requiredType.equals(javaUtilOptionalEmpty.getClass())) {
					convertedValue = javaUtilOptionalEmpty;
				}
			}

			if (!ClassUtils.isAssignableValue(requiredType, convertedValue)) {
				if (conversionAttemptEx != null) {
					// Original exception from former ConversionService call above...
					throw conversionAttemptEx;
				}
				else if (conversionService != null) {
					// ConversionService not tried before, probably custom editor found
					// but editor couldn't produce the required type...
					TypeDescriptor sourceTypeDesc = TypeDescriptor.forObject(newValue);
					if (conversionService.canConvert(sourceTypeDesc, typeDescriptor)) {
						return (T) conversionService.convert(newValue, sourceTypeDesc, typeDescriptor);
					}
				}

				// Definitely doesn't match: throw IllegalArgumentException/IllegalStateException
				StringBuilder msg = new StringBuilder();
				msg.append("Cannot convert value of type [").append(ClassUtils.getDescriptiveType(newValue));
				msg.append("] to required type [").append(ClassUtils.getQualifiedName(requiredType)).append("]");
				if (propertyName != null) {
					msg.append(" for property '").append(propertyName).append("'");
				}
				if (editor != null) {
					msg.append(": PropertyEditor [").append(editor.getClass().getName()).append(
							"] returned inappropriate value of type [").append(
							ClassUtils.getDescriptiveType(convertedValue)).append("]");
					throw new IllegalArgumentException(msg.toString());
				}
				else {
					msg.append(": no matching editors or conversion strategy found");
					throw new IllegalStateException(msg.toString());
				}
			}
		}

		if (conversionAttemptEx != null) {
			if (editor == null && !standardConversion && requiredType != null && Object.class != requiredType) {
				throw conversionAttemptEx;
			}
			logger.debug("Original ConversionService attempt failed - ignored since " +
					"PropertyEditor based conversion eventually succeeded", conversionAttemptEx);
		}

		return (T) convertedValue;
	}

	//基本参数封装
	@Override   
	public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
		Assert.notNull(targetType, "targetType to convert to cannot be null");
		if (sourceType == null) {
			Assert.isTrue(source == null, "source must be [null] if sourceType == [null]");
			return handleResult(null, targetType, convertNullSource(null, targetType));
		}
		if (source != null && !sourceType.getObjectType().isInstance(source)) {
			throw new IllegalArgumentException("source to convert from must be an instance of " +
					sourceType + "; instead it was a " + source.getClass().getName());
		}
		//测试：converter：NO_OP
		//getConverter方法不清楚
		GenericConverter converter = getConverter(sourceType, targetType);
		if (converter != null) {
			//invokeConverter方法后面有详细介绍
			Object result = ConversionUtils.invokeConverter(converter, source, sourceType, targetType);
			//handleResult：1.普通参数就返回结果
			return handleResult(sourceType, targetType, result);
		}
		return handleConverterNotFound(source, sourceType, targetType);
	}
	
	//普通参数
	public static Object invokeConverter(GenericConverter converter, Object source, TypeDescriptor sourceType,
			TypeDescriptor targetType) {
		try {
			//convert方法后面有详细介绍
			return converter.convert(source, sourceType, targetType);
		}
		catch (ConversionFailedException ex) {
			throw ex;
		}
		catch (Exception ex) {
			throw new ConversionFailedException(sourceType, targetType, source, ex);
		}
	}

	//普通参数：
	@Override
	public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
			return source;
		}
	
	//
	protected Object doInvoke(Object... args) throws Exception {
		//判断没进，方法不清楚
		ReflectionUtils.makeAccessible(getBridgedMethod());
		try {
			//获得方法并执行
			return getBridgedMethod().invoke(getBean(), args);
		}
		catch (IllegalArgumentException ex) {
			assertTargetBean(getBridgedMethod(), getBean(), args);
			throw new IllegalStateException(getInvocationErrorMessage(ex.getMessage(), args), ex);
		}
		catch (InvocationTargetException ex) {
			// Unwrap for HandlerExceptionResolvers ...
			Throwable targetException = ex.getTargetException();
			if (targetException instanceof RuntimeException) {
				throw (RuntimeException) targetException;
			}
			else if (targetException instanceof Error) {
				throw (Error) targetException;
			}
			else if (targetException instanceof Exception) {
				throw (Exception) targetException;
			}
			else {
				String msg = getInvocationErrorMessage("Failed to invoke controller method", args);
				throw new IllegalStateException(msg, targetException);
			}
		}
	}		
	
	类ViewNameMethodReturnValueHandler：（返回页面）	
	@Override
	public void handleReturnValue(Object returnValue, MethodParameter returnType,
			ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {

		if (returnValue instanceof CharSequence) {
			//测试：viewName：mvc
			String viewName = returnValue.toString();
			mavContainer.setViewName(viewName);
			//看：判断是否重定向
			if (isRedirectViewName(viewName)) {
				mavContainer.setRedirectModelScenario(true);
			}
		}
		else if (returnValue != null){
			// should not happen
			throw new UnsupportedOperationException("Unexpected return type: " +
					returnType.getParameterType().getName() + " in method: " + returnType.getMethod());
		}
	}	

	类RequestMappingHandlerAdapter：（返回页面）
	private ModelAndView getModelAndView(ModelAndViewContainer mavContainer,
			ModelFactory modelFactory, NativeWebRequest webRequest) throws Exception {

		//updateModel方法不清楚
		modelFactory.updateModel(webRequest, mavContainer);
		if (mavContainer.isRequestHandled()) {
			return null;
		}
		//model:{user=com.dodi.spring.mvc.User@6032fc6b, org.springframework.validation.BindingResult.user=org.springframework.validation.BeanPropertyBindingResult: 0 errors}
		ModelMap model = mavContainer.getModel();
		ModelAndView mav = new ModelAndView(mavContainer.getViewName(), model);
		if (!mavContainer.isViewReference()) {
			mav.setView((View) mavContainer.getView());
		}
		if (model instanceof RedirectAttributes) {
			Map<String, ?> flashAttributes = ((RedirectAttributes) model).getFlashAttributes();
			HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
			RequestContextUtils.getOutputFlashMap(request).putAll(flashAttributes);
		}
		return mav;
	}	

	类DispatcherServlet：（返回页面）
	private void processDispatchResult(HttpServletRequest request, HttpServletResponse response,
			HandlerExecutionChain mappedHandler, ModelAndView mv, Exception exception) throws Exception {

		boolean errorView = false;

		//猜：异常时处理
		if (exception != null) {
			if (exception instanceof ModelAndViewDefiningException) {
				logger.debug("ModelAndViewDefiningException encountered", exception);
				mv = ((ModelAndViewDefiningException) exception).getModelAndView();
			}
			else {
				Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);
				mv = processHandlerException(request, response, handler, exception);
				errorView = (mv != null);
			}
		}

		// Did the handler return a view to render?
		if (mv != null && !mv.wasCleared()) {
			//render方法后面有详细介绍    （--重要--）
			render(mv, request, response);
			if (errorView) {
				WebUtils.clearErrorRequestAttributes(request);
			}
		}
		else {
			if (logger.isDebugEnabled()) {
				logger.debug("Null ModelAndView returned to DispatcherServlet with name '" + getServletName() +
						"': assuming HandlerAdapter completed request handling");
			}
		}

		if (WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {
			// Concurrent handling started during a forward
			return;
		}

		if (mappedHandler != null) {
			mappedHandler.triggerAfterCompletion(request, response, null);
		}
	}
	类DispatcherServlet：（返回页面）
	protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {
		// Determine locale for request and apply it to the response.
		//测试：获得字符集zh_CN
		Locale locale = this.localeResolver.resolveLocale(request);
		response.setLocale(locale);

		View view;
		
		if (mv.isReference()) {
			// We need to resolve the view name.
			//resolveViewName方法后面有详细介绍
			//Controller返回的参数为Stirng时进这里
			view = resolveViewName(mv.getViewName(), mv.getModelInternal(), locale, request);
			if (view == null) {
				throw new ServletException("Could not resolve view with name '" + mv.getViewName() +
						"' in servlet with name '" + getServletName() + "'");
			}
		}
		else {
			// No need to lookup: the ModelAndView object contains the actual View object.
			view = mv.getView();
			if (view == null) {
				throw new ServletException("ModelAndView [" + mv + "] neither contains a view name nor a " +
						"View object in servlet with name '" + getServletName() + "'");
			}
		}

		// Delegate to the View object for rendering.
		if (logger.isDebugEnabled()) {
			logger.debug("Rendering view [" + view + "] in DispatcherServlet with name '" + getServletName() + "'");
		}
		try {
			//render方法后面有详细介绍
			view.render(mv.getModelInternal(), request, response);
		}
		catch (Exception ex) {
			if (logger.isDebugEnabled()) {
				logger.debug("Error rendering view [" + view + "] in DispatcherServlet with name '" +
						getServletName() + "'", ex);
			}
			throw ex;
		}
	}

	类DispatcherServlet：（返回页面）
	protected View resolveViewName(String viewName, Map<String, Object> model, Locale locale,
			HttpServletRequest request) throws Exception {

		for (ViewResolver viewResolver : this.viewResolvers) {
			//resolveViewName方法后面有详细介绍
			View view = viewResolver.resolveViewName(viewName, locale);
			if (view != null) {
				return view;
			}
		}
		return null;
	}

	类AbstractCachingViewResolver：（返回页面）
	@Override
	public View resolveViewName(String viewName, Locale locale) throws Exception {
		if (!isCache()) {
			//（不存在缓存的情况下直接创建视图）
			return createView(viewName, locale);
		}
		else {
			//（直接从缓存中提取）
			//测试：cacheKey：mvc
			Object cacheKey = getCacheKey(viewName, locale);
			View view = this.viewAccessCache.get(cacheKey);
			//双重判断加锁，既保证了线程安全，也保证效率
			if (view == null) {
				synchronized (this.viewCreationCache) {
					view = this.viewCreationCache.get(cacheKey);
					if (view == null) {
						// Ask the subclass to create the View object.
						//createView方法后面有详细介绍
						view = createView(viewName, locale);
						if (view == null && this.cacheUnresolved) {
							view = UNRESOLVED_VIEW;
						}
						if (view != null) {
							//放到缓存中
							this.viewAccessCache.put(cacheKey, view);
							this.viewCreationCache.put(cacheKey, view);
							if (logger.isTraceEnabled()) {
								logger.trace("Cached view [" + cacheKey + "]");
							}
						}
					}
				}
			}
			return (view != UNRESOLVED_VIEW ? view : null);
		}
	}

	@Override
	protected View createView(String viewName, Locale locale) throws Exception {
		// If this resolver is not supposed to handle the given view,
		// return null to pass on to the next resolver in the chain.
		//（如果当前解析器不支持当前解析器如viewName为空等情况）
		if (!canHandle(viewName, locale)) {
			return null;
		}
		// Check for special "redirect:" prefix.
		//（处理前缀为redirect:xx的情况）
		if (viewName.startsWith(REDIRECT_URL_PREFIX)) {
			String redirectUrl = viewName.substring(REDIRECT_URL_PREFIX.length());
			RedirectView view = new RedirectView(redirectUrl, isRedirectContextRelative(), isRedirectHttp10Compatible());
			return applyLifecycleMethods(viewName, view);
		}
		// Check for special "forward:" prefix.
		//（处理前缀为forward:xx的情况）
		if (viewName.startsWith(FORWARD_URL_PREFIX)) {
			String forwardUrl = viewName.substring(FORWARD_URL_PREFIX.length());
			return new InternalResourceView(forwardUrl);
		}
		// Else fall back to superclass implementation: calling loadView.
		//createView方法后面有详细介绍
		return super.createView(viewName, locale);
	}	
	
	protected View createView(String viewName, Locale locale) throws Exception {
		return loadView(viewName, locale);
	}
	
	@Override
	protected View loadView(String viewName, Locale locale) throws Exception {
		//buildView方法后面有详细介绍
		AbstractUrlBasedView view = buildView(viewName);
		//测试：result：org.springframework.web.servlet.view.JstlView: name 'mvc'; URL [/WEB-INF/jsp/mvc.jsp]
		//猜：初始化bean方法
		View result = applyLifecycleMethods(viewName, view);
		return (view.checkResource(locale) ? result : null);
	}

	protected AbstractUrlBasedView buildView(String viewName) throws Exception {
		//测试：view：org.springframework.web.servlet.view.JstlView: unnamed; URL [null]
		AbstractUrlBasedView view = (AbstractUrlBasedView) BeanUtils.instantiateClass(getViewClass());
		
		//（添加前缀以及后缀）
		view.setUrl(getPrefix() + viewName + getSuffix());

		//测试：contentType：null
		String contentType = getContentType();
		if (contentType != null) {
			//（设置ContentType）
			view.setContentType(contentType);
		}

		//测试：以下全部set值都为空
		view.setRequestContextAttribute(getRequestContextAttribute());
		view.setAttributesMap(getAttributesMap());

		Boolean exposePathVariables = getExposePathVariables();
		if (exposePathVariables != null) {
			view.setExposePathVariables(exposePathVariables);
		}
		Boolean exposeContextBeansAsAttributes = getExposeContextBeansAsAttributes();
		if (exposeContextBeansAsAttributes != null) {
			view.setExposeContextBeansAsAttributes(exposeContextBeansAsAttributes);
		}
		String[] exposedContextBeanNames = getExposedContextBeanNames();
		if (exposedContextBeanNames != null) {
			view.setExposedContextBeanNames(exposedContextBeanNames);
		}

		return view;
	}	

	类AbstractView：（返回页面）
	@Override
	public void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
		if (logger.isTraceEnabled()) {
			logger.trace("Rendering view with name '" + this.beanName + "' with model " + model +
				" and static attributes " + this.staticAttributes);
		}
		//createMergedOutputModel方法后面有详细介绍
		//猜：createMergedOutputModel方法把所有参数放到一个map中
		Map<String, Object> mergedModel = createMergedOutputModel(model, request, response);
		//判断为空，没进
		prepareResponse(request, response);
		//renderMergedOutputModel方法后面有详细介绍
		renderMergedOutputModel(mergedModel, getRequestToExpose(request), response);
	}

	protected Map<String, Object> createMergedOutputModel(Map<String, ?> model, HttpServletRequest request,
			HttpServletResponse response) {

		@SuppressWarnings("unchecked")
		//pathVars:null
		Map<String, Object> pathVars = (this.exposePathVariables ?
				(Map<String, Object>) request.getAttribute(View.PATH_VARIABLES) : null);

		// Consolidate static and dynamic model attributes.
		int size = this.staticAttributes.size();
		size += (model != null ? model.size() : 0);
		size += (pathVars != null ? pathVars.size() : 0);

		Map<String, Object> mergedModel = new LinkedHashMap<String, Object>(size);
		mergedModel.putAll(this.staticAttributes);
		if (pathVars != null) {
			mergedModel.putAll(pathVars);
		}
		if (model != null) {
			mergedModel.putAll(model);
		}

		// Expose RequestContext?
		if (this.requestContextAttribute != null) {
			mergedModel.put(this.requestContextAttribute, createRequestContext(request, response, mergedModel));
		}

		return mergedModel;
	}	

	（返回页面）
	@Override
	protected void renderMergedOutputModel(
			Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {

		// Expose the model object as request attributes.
		//（将model中的数据以属性的方式设置到request中）
		exposeModelAsRequestAttributes(model, request);

		// Expose helpers as request attributes, if any.
		//exposeHelpers方法不清楚
		exposeHelpers(request);

		// Determine the path for the request dispatcher.
		//猜：获得跳转路径
		String dispatcherPath = prepareForRendering(request, response);

		// Obtain a RequestDispatcher for the target resource (typically a JSP).
		//猜：rd：org.apache.catalina.core.ApplicationDispatcher@115c5794
		RequestDispatcher rd = getRequestDispatcher(request, dispatcherPath);
		if (rd == null) {
			throw new ServletException("Could not get RequestDispatcher for [" + getUrl() +
					"]: Check that the corresponding file exists within your web application archive!");
		}

		// If already included or response already committed, perform include, else forward.
		//判断没进这里
		if (useInclude(request, response)) {
			response.setContentType(getContentType());
			if (logger.isDebugEnabled()) {
				logger.debug("Including resource [" + getUrl() + "] in InternalResourceView '" + getBeanName() + "'");
			}
			rd.include(request, response);
		}

		else {
			// Note: The forwarded resource is supposed to determine the content type itself.
			if (logger.isDebugEnabled()) {
				logger.debug("Forwarding to resource [" + getUrl() + "] in InternalResourceView '" + getBeanName() + "'");
			}
			//调用servlet方法转发
			rd.forward(request, response);
		}
	}
	
	
11.4.8 异常视图处理（没测试，没找到）

11.4.9 根据视图跳转页面



第12章     远程服务


12.1.2 服务端的实现

	类RmiServiceExporter：
	@Override
	public void afterPropertiesSet() throws RemoteException {
		prepare();
	}

	类RmiServiceExporter：	
	public void prepare() throws RemoteException {
		//（检查验证service）
		//看:判断容器中是否有服务的service，如果没有抛异常
		checkService();

		if (this.serviceName == null) {
			throw new IllegalArgumentException("Property 'serviceName' is required");
		}

		// Check socket factories for exported object.
		/*
		（如果用户在配置文件中配置了clientsocketFactory或者serverSocketFactory接口那么会忽略
			如果配置中的clientSocketFactory同时又实现了RMIServerSocketFactory接口那么会忽略
			配置中的serverSocketFactory而使用clientSocketFactory代替
		）
		*/
		//测试：判断没进为false
		if (this.clientSocketFactory instanceof RMIServerSocketFactory) {
			this.serverSocketFactory = (RMIServerSocketFactory) this.clientSocketFactory;
		}
		//（clientSocketFactory和serverSocketFactory要么同时出现要么都不出现）
		//测试：判断没进，都为null
		if ((this.clientSocketFactory != null && this.serverSocketFactory == null) ||
				(this.clientSocketFactory == null && this.serverSocketFactory != null)) {
			throw new IllegalArgumentException(
					"Both RMIClientSocketFactory and RMIServerSocketFactory or none required");
		}

		// Check socket factories for RMI registry.
		//（如果配置中的registryClientSocketFactory同时实现了RMIServerSocketFactory接口那么）
		//（会忽略配置中的registryServerSocketFactory而使用registryClientSocketFactory代替）
		//测试：判断没进，为null		
		if (this.registryClientSocketFactory instanceof RMIServerSocketFactory) {
			this.registryServerSocketFactory = (RMIServerSocketFactory) this.registryClientSocketFactory;
		}
		//（不允许出现只配置registryServerSocketFactory却没有配置registryClientSocketFactory的情况出现）
		//测试：判断没进，都为null		
		if (this.registryClientSocketFactory == null && this.registryServerSocketFactory != null) {
			throw new IllegalArgumentException(
					"RMIServerSocketFactory without RMIClientSocketFactory for registry not supported");
		}

		this.createdRegistry = false;

		// Determine RMI registry to use.
		//（确定RMI registry）
		if (this.registry == null) {
			//getRegistry方法后面有详细介绍
			//测试this.registry：RegistryImpl[UnicastServerRef [liveRef: [endpoint:[192.168.9.68:9999](local),objID:[0:0:0, 0]]]]
			this.registry = getRegistry(this.registryHost, this.registryPort,
				this.registryClientSocketFactory, this.registryServerSocketFactory);
			this.createdRegistry = true;
		}

		// Initialize and cache exported object.
		//（初始化以及缓存导出的Object）
		//（此时通常情况下是使用RMIInvocationWrapper封装的JDK代理类，切而为RemoteInvocationTraceInterceptor）
		//getObjectToExport方法后面有详细介绍
		this.exportedObject = getObjectToExport();

		if (logger.isInfoEnabled()) {
			logger.info("Binding service '" + this.serviceName + "' to RMI registry: " + this.registry);
		}

		// Export RMI object.
		if (this.clientSocketFactory != null) {
			/*
			（使用由给定的套接字工厂指定的传送方式导出远程对象，以便能够接收传入的调用
				clientSocketFactory：进行远程对象调用的客户端套接字工厂
				serverSocketFactory：接收远程调用的服务端套接字工厂
			）
			*/
			UnicastRemoteObject.exportObject(
					this.exportedObject, this.servicePort, this.clientSocketFactory, this.serverSocketFactory);
		}
		else {
			//（导出remot object，以使它能接收特定端口的调用）
			UnicastRemoteObject.exportObject(this.exportedObject, this.servicePort);
		}

		// Bind RMI object to registry.
		try {
			if (this.replaceExistingBinding) {
				this.registry.rebind(this.serviceName, this.exportedObject);
			}
			else {
				//（绑定服务名称到remote object，外界调用serviceName的时候会被exportedObject）
				this.registry.bind(this.serviceName, this.exportedObject);
			}
		}
		catch (AlreadyBoundException ex) {
			// Already an RMI object bound for the specified service name...
			unexportObjectSilently();
			throw new IllegalStateException(
					"Already an RMI object bound for name '"  + this.serviceName + "': " + ex.toString());
		}
		catch (RemoteException ex) {
			// Registry binding failed: let's unexport the RMI object as well.
			unexportObjectSilently();
			throw ex;
		}
	}

1.获取registry	
	类RmiServiceExporter：		
	protected Registry getRegistry(String registryHost, int registryPort,
			RMIClientSocketFactory clientSocketFactory, RMIServerSocketFactory serverSocketFactory)
			throws RemoteException {

		if (registryHost != null) {
			// Host explicitly specified: only lookup possible.
			//（远程连接测试）
			if (logger.isInfoEnabled()) {
				logger.info("Looking for RMI registry at port '" + registryPort + "' of host [" + registryHost + "]");
			}
			//（如果registryHost不为空则尝试获取对应主机的Registry）
			Registry reg = LocateRegistry.getRegistry(registryHost, registryPort, clientSocketFactory);
			testRegistry(reg);
			return reg;
		}
		//测试：判断进这里
		else {
			//（获取本机的Registry）
			//getRegistry方法后面有详细介绍
			return getRegistry(registryPort, clientSocketFactory, serverSocketFactory);
		}
	}	
	
	类RmiServiceExporter：	
	protected Registry getRegistry(
			int registryPort, RMIClientSocketFactory clientSocketFactory, RMIServerSocketFactory serverSocketFactory)
			throws RemoteException {

			
		if (clientSocketFactory != null) {
			if (this.alwaysCreateRegistry) {
				logger.info("Creating new RMI registry");
				//（使用clientSocketFactory创建Registry）
				return LocateRegistry.createRegistry(registryPort, clientSocketFactory, serverSocketFactory);
			}
			if (logger.isInfoEnabled()) {
				logger.info("Looking for RMI registry at port '" + registryPort + "', using custom socket factory");
			}
			synchronized (LocateRegistry.class) {
				try {
					// Retrieve existing registry.
					//（复用测试）
					Registry reg = LocateRegistry.getRegistry(null, registryPort, clientSocketFactory);
					testRegistry(reg);
					return reg;
				}
				catch (RemoteException ex) {
					logger.debug("RMI registry access threw exception", ex);
					logger.info("Could not detect RMI registry - creating new one");
					// Assume no registry found -> create new one.
					return LocateRegistry.createRegistry(registryPort, clientSocketFactory, serverSocketFactory);
				}
			}
		}
		//测试：判断进这里
		else {
			//getRegistry方法后面有详细介绍
			return getRegistry(registryPort);
		}
	}

	类RmiServiceExporter：	
	protected Registry getRegistry(int registryPort) throws RemoteException {
		//测试：判断没进，alwaysCreateRegistry为false
		if (this.alwaysCreateRegistry) {
			logger.info("Creating new RMI registry");
			return LocateRegistry.createRegistry(registryPort);
		}
		if (logger.isInfoEnabled()) {
			logger.info("Looking for RMI registry at port '" + registryPort + "'");
		}
		synchronized (LocateRegistry.class) {
			try {
				// Retrieve existing registry.
				//（查看对应当前registryPort的Registry是否已经创建，如果创建直接使用）
				//测试：reg：RegistryImpl_Stub[UnicastRef [liveRef: [endpoint:[192.168.9.68:9999](remote),objID:[0:0:0, 0]]]]
				//猜：获得本地的ip和使用的端口
				Registry reg = LocateRegistry.getRegistry(registryPort);
				//（测试是否可用，如果不可用则抛出异常）
				testRegistry(reg);
				return reg;
			}
			catch (RemoteException ex) {
				logger.debug("RMI registry access threw exception", ex);
				logger.info("Could not detect RMI registry - creating new one");
				// Assume no registry found -> create new one.
				//（根据端口创建Registry）
				//测试进这里
				//创建一个新的RegistryImpl对象
				return LocateRegistry.createRegistry(registryPort);
			}
		}
	}

2.初始化将要导出的实体对象	
	
	类RmiServiceExporter：		
	protected Remote getObjectToExport() {
		// determine remote object
		//（如果配置的service属性对应的类实现了Remote接口且没有配置serviceInterface属性）
		if (getService() instanceof Remote &&
				(getServiceInterface() == null || Remote.class.isAssignableFrom(getServiceInterface()))) {
			// conventional RMI service
			return (Remote) getService();
		}
		else {
			// RMI invoker
			if (logger.isDebugEnabled()) {
				logger.debug("RMI service [" + getService() + "] is an RMI invoker");
			}
			//测试进入这里
			//（对service进行封装）
			//getProxyForService方法后面有详细介绍
			return new RmiInvocationWrapper(getProxyForService(), this);
		}
	}

	类RemoteExporter：
	protected Object getProxyForService() {
		//（验证servcie）
		checkService();
		//（验证serviceInterface）
		checkServiceInterface();
		//（使用JDK的方式创建代理）
		ProxyFactory proxyFactory = new ProxyFactory();
		//（添加代理接口）
		proxyFactory.addInterface(getServiceInterface());
		if (this.registerTraceInterceptor != null ?
				this.registerTraceInterceptor.booleanValue() : this.interceptors == null) {
			//（加入代理的模切面RemoteInvocationTraceInterceptor并记录Exporter名称）
			//RemoteInvocationTraceInterceptor方法后面有详细介绍
			proxyFactory.addAdvice(new RemoteInvocationTraceInterceptor(getExporterName()));
		}
		if (this.interceptors != null) {
			AdvisorAdapterRegistry adapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
			for (int i = 0; i < this.interceptors.length; i++) {
				proxyFactory.addAdvisor(adapterRegistry.wrap(this.interceptors[i]));
			}
		}
		//（设置要代理的目标类）
		proxyFactory.setTarget(getService());
		proxyFactory.setOpaque(true);
		//（创建代理）
		return proxyFactory.getProxy(getBeanClassLoader());
	}	
	
	
	